1. Two Sum (快速排序;有序数组的查找: 两个指针; 哈希表)

Given an array of integers, return indices of the two numbers such that they add up to a specific target.

You may assume that each input would have exactly one solution.

Example:
Given nums = [2, 7, 11, 15], target = 9,

Because nums[0] + nums[1] = 2 + 7 = 9,
return [0, 1].

方法I: 先快速排序,再通过头尾指针遍历,时间复杂度O(nlogn)

typedef struct MyNum{
    int num;
    int index;
}MyNum;

int* twoSum(int* nums, int numsSize, int target) {
    int start = 0;
    int end = numsSize-1;
    int* result = NULL;
    MyNum* myNums;
    int sum;
    
    if(numsSize < 2) return result;
    
    result = malloc(sizeof(int)*2);
    myNums = malloc(sizeof(MyNum)*numsSize);
    for(int i = 0; i < numsSize; i++){
        myNums[i].num = nums[i];
        myNums[i].index = i;
    }
    
    quickSort(myNums, start, end);

    sum = myNums[start].num+myNums[end].num;
    while(sum != target){
        if(sum > target) end--;
        else start++;
        sum = myNums[start].num+myNums[end].num;
    }
    
    if(myNums[start].index <= myNums[end].index){
        result[0] = myNums[start].index;
        result[1] = myNums[end].index;
    }
    else{
        result[1] = myNums[start].index;
        result[0] = myNums[end].index;
    }
    return result;
}

void quickSort(MyNum* nums, int start, int end){
    int p1 = start+1; 
    int p2 = end;
    MyNum tmp;

    while(p1 <= p2){
        while(p1 <= p2 && nums[p1].num <= nums[start].num ){
            p1++;
        }
        while(p1 <= p2 && nums[p2].num > nums[start].num ){
            p2--;
        }
        if(p1 < p2){
            tmp = nums[p1];
            nums[p1] = nums[p2];
            nums[p2] = tmp;
            p1++;
            p2--;
        }
    }

    //put the sentinel at the end of the first subarray
    if(start!=p2){
    tmp = nums[start];
    nums[start] = nums[p2];
    nums[p2] = tmp;
    }
            
    if(start < p2-1) quickSort(nums,start, p2-1); //sort first subarray (<=sentinel)
    if(p1 < end) quickSort(nums,p1, end); //sort second subarray  (>sentinel)
}

方法II:哈希表,时间复杂度O(n)

typedef struct HashElem{
    int value;
    int num;
    struct HashElem* next;
};

int* twoSum(int* nums, int numsSize, int target) {
    int start = 0;
    int end = numsSize-1;
    struct HashElem* p = NULL;
    struct HashElem* hashTable[997];
    int key;
    int result[2];
    
    if(numsSize < 2) return result;
    
    //initialize
    for(int i = 0; i < 997; i++){
        hashTable[i] = NULL;
    }
    //build hash table
    for(int i = 0; i < numsSize; i++){
        key = abs(nums[i]%997); //用余数法作为哈希函数,要注意负数的情况

        struct HashElem* ln = malloc(sizeof(struct HashElem));
        ln->value = i;
        ln->num = nums[i];
        ln->next = hashTable[key];
        hashTable[key] = ln;
    }
    
    //find the element in hash table
    for(int i = 0; i < numsSize; i++){
        key = abs((target-nums[i])%997);
        p = hashTable[key];
        while(p && (p->num!= target-nums[i]|| p->value==i)) p = p->next;
        if(p){
            result[0] = i;
            result[1] = p->value;
            break;
        }
    }
    return result;
}
原文地址:https://www.cnblogs.com/qionglouyuyu/p/5267871.html