【icyle】Leetcode-cn:16. 最接近的三数之和

题目

解答:排序+双指针

思路(大白话)

参考15. 三数之和的思路,只需要考虑以下两个点:

  • 因为是找最接近的,所以一般情况下需要把全部情况列出来,除非直接找到了target数,可以直接返回target。
  • 需要定义一个新的变量作为差值=sum-target,一旦存在更小的差值,就把sum和其对应的差值存储下来,最后返回对应差值最小的sum即可。
需要的头文件

vector、algorithm

代码
/*
 * @lc app=leetcode.cn id=16 lang=cpp
 *
 * [16] 最接近的三数之和
 */

// @lc code=start
#include <vector>
#include <algorithm>
using namespace std;
class Solution
{
public:
    int threeSumClosest(vector<int> &nums, int target)
    {
        int numslength = nums.size();
        //特殊情况
        if (numslength == 3)
        {
            return nums[0] + nums[1] + nums[2];
        }

        //restg:返回值
        //threesum:计算过程中三个数的值
        //dist:threesum和target的差值
        int restg = 0;
        int threesum = 0;
        int dist = INT_MAX;

        sort(nums.begin(), nums.end());
        //这里排序加双指针法比较好理解,重点是要如何减少查询次数
        //1. 一重循环和二重循环重复的数不再查
        //一重循环比如[1,1,1,3,4,5],第一个1和第二个1如果都查,那么类似[1,3,4][1,3,5]这种就重复了
        //二重循环比如上面例子的第一个1固定,第一次查找是[1,1]+[1,3,4,5]中的一个,第二次查找是[1,1]+[3,4,5]中的一个,就有重复了
        for (int i = 0; i < numslength; i++)
        {
            //注意这里不要漏i>0,因为一开始i=0的话,i-1是非法的
            if (i > 0 && nums[i] == nums[i - 1])
            {
                continue;
            }
            int left = i + 1, right = numslength - 1;
            while (left < right)
            {
                threesum = nums[i] + nums[left] + nums[right];
                if (abs(threesum - target) < dist)
                {
                    dist = abs(threesum - target);
                    restg = threesum;
                }

                // 如果直接就是target,那么可以直接返回
                if (threesum == target)
                {
                    return target;
                }
                // 如果小了,左指针往右;如果大了,右指针往左
                else if (threesum < target)
                {
                    left++;
                }
                else if (threesum > target)
                {
                    right--;
                }
            }
        }
        return restg;
    }
};
// @lc code=end
时间复杂度和空间复杂度
  • 时间复杂度: O(n2) ,原理同15题。简单来说就是第一个数循环是 O(n) ,双指针循环也是 O(n) ,叠加就是 O(n2)

  • 空间复杂度:如果本题不允许修改nums,那么我们需要复制一份相同的数组,然后对其进行排序。复制一份的时间复杂度为 O(n) ,排序的时间复杂度为 O(logn) ,渐进情况下得到总的时间复杂度为 O(n)

反思与总结

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值