LeetCode刷题笔记—最接近的三数之和

最接近的三数之和


最接近的三数之和

原题地址:最接近的三数之和

题目描述:

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。

返回这三个数的和。

假定每组输入只存在恰好一个解。

示例1:

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

示例2:

输入:nums = [0,0,0], target = 1
输出:0

思路:

相对于三数之和,这道题目的唯一区别在于:

这次数组中的三个数相加有可能取不到target,这里要返回三数相加最接近target的和。

那对于这道题目,类似的,我们仍然可以考虑用排序+双指针的方法。

具体做法如下:

1.先对原数组进行一次排序

2.然后一层for循环固定一个元素。

3.循环体内部使用双指针在固定元素之和的部分中找剩下符合题意的两个元素。

4.第一个指针指向剩余部分的第一个元素,第二个指针指向数组最后一个元素

5.求三个元素之和,若等于0,直接返回(因为不可能存在更接近的了);剩下情况,计算当前和与历史和之间差与差的绝对值,若差大于0,第二个指针左移;若差小于0,第一个指针右移。若差的绝对值小于0,则将当前和赋给历史和。

6.当两个指针相遇,继续第一层for循环。

7.最后返回历史和。
在这里插入图片描述
代码如下:

class Solution:
    def threeSumClosest(self, nums: List[int], target: int) -> int:
        n = len(nums)
        nums.sort()
        res =  nums[0] + nums[1] + nums[2] # 用数组元素初始化,一般是起始元素

        for i in range(n - 2):  # 找三个元素,先固定一个,然后从剩下的部分里面找两个元素,取值范围可不就是0~n-3嘛
            if i > 0 and nums[i] == nums[i-1]: # 去重
                continue
            # 双指针
            left = i+1  # 第一个指针位置为i向右移动一位
            right = n-1  # 第二个指针位置为数组末位
            while (left < right):
                if nums[i] + nums[left] + nums[right] == target:
                	return target
                
                if abs(target - nums[i] - nums[left] - nums[right]) < abs(target - res):
                    res = nums[i] + nums[left] + nums[right]
                
                if nums[i] + nums[left] + nums[right] < target:
                    # 当三元素之和小于target时,需要将第一个指针向右移动一位
                    left += 1
                    
                if nums[i] + nums[left] + nums[right] > target:
                    # 当三元素之和大于target时,需要将第二个指针向左移动一位
                    right -= 1
                    
        return res

总结

时间复杂度:

乍一看使用了一个for循环体,两个while循环体,好像复杂度是 O ( n 3 ) O(n^3) O(n3),然而,仔细观察可以看到,其实第二个while循环体(最后的两个while循环看作一个)只是帮助跳过一些重复的元素而已,因此,总的时间复杂度还是 O ( n 2 ) O(n^2) O(n2)

空间复杂度:

不确定,取决于排序算法的内部实现过程。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值