最接近的三数之和

给定一个包括 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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/3sum-closest

解题思路

暴力解法

根据题目可以知道,一定是三个数的和。因此可以对数组进行三次遍历。并且使用两个临时变量存储结果值和结果值与target差值的绝对值。将每一层遍历的元素累加,与target进行判断。取与target差值的绝对值最小的值。

代码
func threeSumClosest(nums []int, target int) int {
	result,diff := 0,math.MaxInt64
	for i:=0;i<len(nums);i++{
		for j:=i+1;j<len(nums);j++{
			for k:=j+1;k<len(nums);k++{
				sum := nums[i] + nums[j] + nums[k]
				tmp := int(math.Abs(float64(sum - target)))
				if tmp < diff {
					diff = tmp
					result = sum
				}
			}
		}
	}
	return result
}

进阶做法

暴力解法是使用三层循环。优化的思路是减少循环的层数,因为考虑到三层循环可以相当于指导一个数,然后再对接下来的数组进行双指针运算可以代替三层循环。使用双指针之前应先将数组进行排序。进阶的难点在于使用双指针之后,如何驱动指针的指向。

这里我也是用两个临时变量:result和diff,result用来存储结果值,diff用来存储结果值和目标值之差的绝对值。x表示头指针,y表示尾指针。sum = nums[i] + nums[x] +nums[y]

  • 如果sum > target。因此为了让结果值接近,可以将y--。这里判断一下是否需要更新result和diff值。
  • 如果sum < target。因此为了让结果接近,可以将x++。这里也判断一下是否需要更新result和diff值。
  • 如果sum==target。直接跳出循环,因为相等了就是最接近的了。
代码
func threeSumClosest(nums []int, target int) int {
	result,diff := 0,math.MaxInt64
	sort.Ints(nums)
	for i:=0;i<len(nums);i++{
		x := i+1
		y := len(nums)-1
		for x<y {
			sum := nums[i] + nums[x] + nums[y]
			if sum < target {
				tmp := int(math.Abs(float64(sum - target)))
				if tmp <= diff {
					result = sum
					diff = tmp
				}
				x++
			}else if sum > target {
				tmp := int(math.Abs(float64(sum - target)))
				if tmp <= diff {
					result = sum
					diff = tmp
				}
				y--
			}else if sum==target {
				return sum
			}
		}
	}
	return result
}

posted @ 2021-06-12 10:33  Myuniverse  阅读(56)  评论(0编辑  收藏  举报