leetcode T1 Detailed two numbers

Two numbers and

Title Description

Given an integer array nums and a target value target, and ask you to identify the target value of the two integers in the array, and return to their array subscript. You can assume that each input corresponds to only one answer. However, you can not re-use the same array element.

Examples

Given nums = [2, 7, 11, 15], target = 9, because nums [0] + nums [1] = 2 + 7 = 9, is returned [0, 1]

method time complexity Space complexity result time RAM
method time complexity Space complexity result time RAM
Violence Enumeration O (N 2 ) O (1) by 180ms 7.6M
Sort double pointer + O (nlog 2 n) O (n) by 96ms 8.4M
Hash O (n) O (n) by 20ms 15.3M

 
 
 
 
 
 

Detailed explanations

Violence Enumeration

Violence idea is very simple: each element of the array nums nums traversal of [i], in [i + 1, ..., numsSize 1-] traversal to find whether there is a j, such that target = nums [i] + nums [ j].

int *twoSum(int *nums, int numsSize, int target, int *returnSize)
{
    int *retArr = NULL;
    int i, j;
    
    for (i = 0; i < numsSize - 1; i++) {
        for (j = i + 1; j < numsSize; j++) {
            if (nums[i] + nums[j] == target) {
                retArr = malloc(sizeof(int) * 2);
                assert(retArr != NULL);
                retArr[0] = i;
                retArr[1] = j;
                *returnSize = 2;
                return retArr;
            }
        }
    }
    
    *returnSize = 0;
    return NULL;
}

Sort double pointer +

If the lookup target is equal to the sum of two numbers in the sorted list, the pointer can be double, enumerated from the two to the intermediate, the time complexity of O (n)
With this in mind, nums first array can be sorted and then with double pointer enumeration, but sort of time to pay attention, we need to bring the original array index to sort

void qsortWithIndex(int *nums, int *indexArr, int left, int right)
{
    int i, j, pivot, pIndex;
    
    if (left >= right) {
        return;
    }
    
    i = left;
    j = right;
    pivot = nums[left];
    pIndex = indexArr[left];
    
    while (i < j) {
        while (i < j && pivot <= nums[j]) {
            j--;
        }
        
        nums[i] = nums[j];
        indexArr[i] = indexArr[j];
        
        while (i < j && pivot >= nums[i]) {
            i++;
        }
        
        nums[j] = nums[i];
        indexArr[j] = indexArr[i];
    }
    
    nums[i] = pivot;
    indexArr[i] = pIndex;
    
    qsortWithIndex(nums, indexArr, left, i - 1);
    qsortWithIndex(nums, indexArr, i + 1, right);
}

int *twoSum(int *nums, int numsSize, int target, int *returnSize)
{
    int *indexArr = NULL;
    int *retArr = NULL;
    int i, j;
    
    indexArr = malloc(sizeof(int) * numsSize);
    assert(indexArr != NULL);
    for (i = 0; i < numsSize; i++) {
        indexArr[i] = i;
    }
    
    qsortWithIndex(nums, indexArr, 0, numsSize - 1);
    
    i = 0;
    j = numsSize - 1;
    while (i < j) {
        if (nums[i] + nums[j] == target) {
            retArr = malloc(sizeof(int) * 2);
            assert(retArr != NULL);
            *returnSize = 2;
            retArr[0] = indexArr[i];
            retArr[1] = indexArr[j];
            free(indexArr);
            return retArr;
        } else if (nums[i] + nums[j] > target) {
            j--;
        } else {
            i++;
        }
    }
    
    free(indexArr);
    *returnSize = 0;
    return NULL;
}

Hash

Using a hash table to store already queried element values and the corresponding index
of each element nums [I] through the array nums the query whether there is target-nums [i] in the hash table elements
, if present , then the corresponding solution found, and if not, then (nums [i], i) is inserted into the hash table

#define MAX_NUMS_SIZE 1000001

typedef struct HashNode {
    int index;
    int value;
} HashNode;

HashNode node[MAX_NUMS_SIZE];

void hashPut(HashNode **hashTable, HashNode *hashNode)
{
    int index;
    
    if (hashNode->value >= 0) {
        index = hashNode->value % MAX_NUMS_SIZE;
    } else {
        index = -1 * hashNode->value % MAX_NUMS_SIZE;
    }
    
    while (hashTable[index]) {
        index = (index + 1) % MAX_NUMS_SIZE;
    }
    
    hashTable[index] = hashNode;
}

HashNode *hashGet(HashNode **hashTable, int value)
{
    int index;
    
    if (value >= 0) {
        index = value % MAX_NUMS_SIZE;
    } else {
        index = -1 * value % MAX_NUMS_SIZE;
    }
    
    while (hashTable[index]) {
        if (hashTable[index]->value != value) {
            index = (index + 1) % MAX_NUMS_SIZE;
        } else {
            return hashTable[index];
        }
    }
    
    return NULL;
}

int *twoSum(int *nums, int numsSize, int target, int *returnSize)
{
    HashNode *hashTable[MAX_NUMS_SIZE] = {NULL};
    HashNode *hashNode = NULL;
    int *retArr = NULL;
    int i;
    
    if (!numsSize || !nums) {
        *returnSize = 0;
        return NULL;
    }
    
    for (i = 0; i < numsSize; i++) {
        hashNode = hashGet(hashTable, target - nums[i]);
        if (hashNode) {
            retArr = malloc(sizeof(int) * 2);
            assert(retArr != NULL);
            *returnSize = 2;
            retArr[0] = hashNode->index;
            retArr[1] = i;
            return retArr;
        }
        
        node[i].index = i;
        node[i].value = nums[i];
        hashPut(hashTable, &node[i]);
    }
    
    *returnSize = 0;
    return NULL;
}

Guess you like

Origin www.cnblogs.com/xiaoxxmu/p/11706643.html