[LeetCode] Two Sum

Given an array of integers, find two numbers such that they add up to
a specific target number.

The function twoSum should return indices of the two numbers such that
they add up to the target, where index1 must be less than index2.
Please note that your returned answers (both index1 and index2) are
not zero-based.

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

Input: numbers={2, 7, 11, 15}, target=9 Output: index1=1, index2=2

BF的方法显然是LTE的
本题的核心是在一个数组中 ,已知array[i],寻找target-array[i],可以为此构建一个map,key_type就是array[i],value_type是target-array[i]。
或是构建一个hash_table,h[key]=target-key.

class Solution {
public:
    vector<int> twoSum(vector<int>& nums, int target) {
        vector<int> v_tmp;
        unordered_map<int,int> v_map;
        //对于每一个nums中的元素item,在map中查找target-item,如果找到则直接保存输出
        //如果没有找到,则将item保存到map中去
        for(vector<int>::size_type vi =0; vi != nums.size(); ++vi){
            unordered_map<int,int>::iterator m_iter = v_map.find(target-nums[vi]) ;
                if(m_iter == v_map.end())             //如果没有找到
                    v_map.insert({nums[vi],vi+1});
                else{
                    v_tmp.push_back(m_iter->second);
                    v_tmp.push_back(vi+1);
                    cout <<"index1="<<m_iter->second<<",index2="<<vi+1;
                    return v_tmp;
                }

        }
        return v_tmp;


    }
};

也可以使用c来写,思路现将数组排序(快排),再对排好序的数组进行二分查找。

/**
 * Note: The returned array must be malloced, assume caller calls free().
 */
 //Swap two numbers
 void swap(int *a, int *b){
     int tmp;
     tmp = *a;
     *a = *b;
     *b = tmp;
 }
 //choose the median of left, center and right
 int median3(int *A, int *index_A, int left, int right){
     int center = (left+right)/2;
     if(A[left]>A[center]){
        swap(A+left,A+center);
        swap(index_A+left,index_A+center);
     }
     if(A[left]>A[right]){
        swap(A+left,A+right);
        swap(index_A+left, index_A+right);
     }
     if(A[center]>A[right]){
        swap(A+center,A+right);
        swap(index_A+center,index_A+right);
     }
     //put median in right-1
     swap(A+center,A+right-1);
     swap(index_A+center,index_A+right-1);
    return A[right-1];
 }

 //Insertion sort ---for small size array and index array
 void Insertion_Sort(int *A, int *index_A, int N){
     int p; int i; int tmp; int index_tmp;
     for(p = 1; p != N; ++p){
         tmp = A[p];
         index_tmp = index_A[p];
         for(i = p; i!=0&&A[i-1]>tmp; --i){
                A[i]=A[i-1];
                index_A[i]=index_A[i-1];
         }
         A[i] = tmp;
         index_A[i]=index_tmp;
     }

 }
 void Quicksort(int *A, int *index_A, int left, int right){
    if(right-left>10){
        int pivot = median3(A, index_A, left, right);
        int i = left; int j = right-1;
        for(;;){
            while(A[++i]<pivot){}
            while(A[--j]>pivot){}
            if(i<j){
                swap(A+i,A+j);
                swap(index_A+i,index_A+j);
            }
            else
                break;
        }
        swap(A+i,A+right-1);
        swap(index_A+i,index_A+right-1);
        Quicksort(A,index_A,left,i-1);
        Quicksort(A,index_A,i+1,right);
    }
    else
        Insertion_Sort(A+left,index_A+left,right-left+1);

 }
 //Binary search
 int Bin_search(int *A, int target, int left, int right){
    int mid =(left+right)/2;
    if(left>right)
        return -1;
    if(target==A[mid])
        return mid;
    else if(target < A[mid])
            return Bin_search(A,target,left,mid-1);
    else
            return Bin_search(A,target,mid+1,right);


 }
 //Quick sort ---sort array A and change the index array index_a consequently
 void Quick_Sort(int *A, int *index_A, int N){
     Quicksort(A,index_A,0,N-1);
 }
int* twoSum(int* nums, int numsSize, int target) {
    int *result = (int *)malloc(2 * sizeof(int));
    int *index_nums = (int *)malloc(numsSize * sizeof(int));
    int index1,index2;
    for(int i = 0; i != numsSize; ++i)
        index_nums[i]= i+1;
    Quick_Sort(nums, index_nums, numsSize);
    for(int i = 0; i != numsSize; ++i){
        index1 = Bin_search(nums,target-nums[i],i+1,numsSize-1);
        index2 = i;
        if(index1!=-1)          //found
            break;
    }
    index1 = index_nums[index1];
    index2 = index_nums[index2];
    if(index1 > index2)
        swap(&index1,&index2);
    result[0]=index1;result[1]=index2;
    return result;
}

有一些trick,在对nums数组进行排序的过程中,但凡涉及到swap操作时,都将其index的伴随数组进行相应的调整,最后运行时间是4ms.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值