LeetCode 16. 3Sum Closest

来源:互联网 发布:淘宝无线端连接在哪里 编辑:程序博客网 时间:2024/05/01 18:26

思路和LeetCode 15. 3Sum很相似

1. 排序数组num

2. 双层迭代,每一层都是和上一次迭代的数字相等时continue

3. 在[j+1, num.size()-1]中二分查找里target-num[i]-num[j]最近的数,复杂度为O(n^2 logn)。这里的trick是:

num = {1, 4, 7, 10, 13, 17, 20}, l = 2, r = 6, target = 14;

这时mid = (2+6)/2= 4, num[mid] = 13 < 14 = target. 若按照经典的二分策略,则l = mid + 1. 

但是,我们发现num[mid] < target < num[mid+1]. 我们考察num[mid]和num[mid+1], 发现比它小的num[mid]更接近target, 因此我们就break掉了迭代。直接返回num[mid]. 如下图的情况2所示:


具体实现可参考binary_search()函数里的while迭代:

class Solution {public:    int threeSumClosest(vector<int> &num, int target)     {    int closest = INT_MAX, ret;    sort(num.begin(), num.end());    for (int i = 0; i < int(num.size())-2; ++ i)    {if (i!=0 && num[i]==num[i-1]){continue;}    for (int j = i+1; j < int(num.size())-1; ++ j)    {    if (j!=i+1 && num[j]==num[j-1])    {    continue;    }    int ans = binary_search(num, target-num[i]-num[j], j+1) ;    if (closest > abs(target-num[i]-num[j]-ans))                {                    closest = abs(target-num[i]-num[j]-ans);                    ret = num[i] + num[j] + ans;                }    }    }       return ret;     }private:int binary_search(vector<int>& num, int target, int l){int r = num.size()-1, mid;while (l <= r){mid = (l+r)/2;if (num[mid] < target){                if (abs(target-num[mid]) >= abs(target-num[mid+1]))                {    l = mid + 1;                } else                {                    break;                }} else if (num[mid] > target){                if (abs(target-num[mid]) >= abs(target-num[mid-1]))                {    r = mid - 1;                } else                {                    break;                }} else{break;}}        return num[mid];}};




0 0
原创粉丝点击