16-最接近的三数之和

题目:

给定一个包括 n 个整数的数组 nums 和 一个目标值 target。找出 nums 中的三个整数,使得它们的和与 target 最接近。返回这三个数的和。假定每组输入只存在唯一答案。

示例:

输入:nums = [-1,2,1,-4], target = 1
输出:2
解释:与 target 最接近的和是 2 (-1 + 2 + 1 = 2) 。
 

提示:

3 <= nums.length <= 10^3
-10^3 <= nums[i] <= 10^3
-10^4 <= target <= 10^4

解答:

参考15题的解法,代码如下:

int threeSumClosest(vector<int>& nums, int target) 
{
    if (nums.size() == 3)
        return nums.at(0) + nums.at(1) + nums.at(2);

    //排序
    sort(nums.begin(), nums.begin() + nums.size());

    long closestNum = INT_MAX;    //这两个类型要大于int,因为下面存在减法,可能溢出
    long sum = 0;
    int idx1 = 0, idx2 = 0;
    for (int i = 0; i < nums.size(); i++)
    {
        if (i > 0 && nums.at(i) == nums.at(i - 1))//第一个数重复的就跳过,避免重复计算
            continue;

        idx1 = i + 1;
        idx2 = nums.size() - 1;
        while (idx1 < idx2)
        {
            sum = nums.at(i) + nums.at(idx1) + nums.at(idx2);
            if (sum == target)
                return sum;

            if (abs(sum - target) < abs(closestNum - target))
                closestNum = sum;

            if (sum < target)
                idx1++;
            else if (sum > target)
                idx2--;
        }
    }

    return closestNum;
}

对上面代码进行一些修改,优化后代码如下:

int threeSumClosest2(vector<int>& nums, int target)
{
    if (nums.size() == 3)
        return nums.at(0) + nums.at(1) + nums.at(2);

    //排序
    sort(nums.begin(), nums.begin() + nums.size());
    
    //输入元素都相等,则直接返回前三个;
    if (nums.at(0) == nums.at(nums.size()-1))
        return nums.at(0) + nums.at(1) + nums.at(2);

    //排除排除一些特殊情况,减少计算
    if ((nums.at(0) + nums.at(1) + nums.at(2)) > target)
        return nums.at(0) + nums.at(1) + nums.at(2);
    if ((nums.at(nums.size() - 1) + nums.at(nums.size() - 2) + nums.at(nums.size() - 3)) < target)
        return (nums.at(nums.size() - 1) + nums.at(nums.size() - 2) + nums.at(nums.size() - 3));


    long closestNum = INT_MAX;    //这两个类型要大于int,因为下面存在减法,可能溢出
    long sum = 0;
    int idx1 = 0, idx2 = 0;
    for (int i = 0; i < nums.size(); i++)
    {
        if (i > 0 && nums.at(i) == nums.at(i - 1))//第一个数重复的就跳过,避免重复计算
            continue;

        idx1 = i + 1;
        idx2 = nums.size() - 1;
        while (idx1 < idx2)
        {
            //这里第二个重复的不能跳过,输入的可能都是相等的值
            //if (idx1 > i+1 && nums.at(idx1) == nums.at(idx1 - 1))//第二个数重复的就跳过,避免重复计算
            //    continue;

            sum = nums.at(i) + nums.at(idx1) + nums.at(idx2);
            if (sum == target)
                return sum;

            if (abs(sum - target) < abs(closestNum - target))
                closestNum = sum;

            if (sum < target)
                idx1++;
            else if (sum > target)
                idx2--;
        }
    }

    return closestNum;
}

 

posted @ 2020-11-13 14:38  adfas  阅读(162)  评论(0编辑  收藏  举报