【每日一题】Day 1
16.最接近的三数之和
题目:
给你一个长度为 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 最接近的和是 0(0 + 0 + 0 = 0)。
提示:
3 <= nums.length <= 1000
-1000 <= nums[i] <= 1000
-104 <= target <= 104
代码实现(Go):
详细注解:
// package main// import (
// "fmt" //格式化
// "math" //计算绝对值
// "sort" //排序
// )func threeSumClosest(nums []int, target int) int {// 先对数组排序,排序后方便使用双指针法来缩小搜索范围。sort.Ints(nums) //默认升序// 初始化结果为前三个数的和。// 选用前三个数是最简单的起点,因为 nums 已经被排序了,// 所以前三个数是数组中最小的三个数,确保初始化的值是一个有效的三数和。ans := nums[0] + nums[1] + nums[2]// 遍历数组,固定第一个数 nums[i]// 遍历到倒数第三个元素即可,因为后面还要选两个数for i := 0; i <= len(nums)-3; i++ {left := i + 1 // 左指针,紧跟在固定数之后right := len(nums) - 1 // 右指针,数组末尾// 双指针遍历,寻找最接近 target 的三数和for left < right {cur := nums[i] + nums[left] + nums[right] // 当前三数和// 如果当前和刚好等于目标,直接返回结果if cur == target {return cur}// 判断当前和是否更接近目标,比之前 closestSum 更接近则更新// 使用 math.Abs 计算绝对值,注意使用Abs必须先转成 float64 类型if math.Abs(float64(cur-target)) < math.Abs(float64(ans-target)) {ans = cur}// 根据当前和与目标的大小关系调整指针if cur < target {left++ // 和小于目标,左指针右移,尝试增大和} else {right-- // 和大于目标,右指针左移,尝试减小和}}}// 遍历完成后返回最接近目标的三数之和return ans
}// func main() {
// // 示例测试用例
// nums := []int{-1, 2, 1, -4}
// target := 1
// fmt.Println(threeSumClosest(nums, target)) // 输出: 2
// }
无注释:
// package main// import (
// "fmt"
// "math"
// "sort"
// )func threeSumClosest(nums []int, target int) int {sort.Ints(nums)ans := nums[0] + nums[1] + nums[2]for i := 0; i <= len(nums)-3; i++ {left := i + 1right := len(nums) - 1for left < right {cur := nums[i] + nums[left] + nums[right]if cur == target {return cur}if math.Abs(float64(cur-target)) < math.Abs(float64(ans-target)) {ans = cur}if cur < target {left++} else {right--}}}return ans
}// func main() {
// nums := []int{0, 1, 2, 3, 4, 5}
// target := threeSumClosest(nums, 0)
// fmt.Println(target)
// }