数组-最接近的三数之和-三数之和-Go语言

题目一

最接近的三数之和

给你一个长度为 n 的整数数组 nums 和 一个目标值 target。请你从 nums 中选出三个整数,使它们的和与 target 最接近。
返回这三个数的和。
假定每组输入只存在恰好一个解。
思路1
最简单的就是暴力求解,直接遍历数组,三重循环,时间复杂度达到O(n) = n^3,具体代码如下(网上copy):

func threeSumClosest(nums []int, target int) int {
	n:=len(nums)
	path:=math.MaxInt64
	//res 就是最后返回的三数之和,初始化为几都可以,最后结果和这个初始化的值无关。res初始化下面的值都可以!!!
	//res :=0
	//res :=10
	res :=nums[0]+nums[1]+nums[2]
	for i:=0;i<n;i++{
		for j:=i+1;j<n;j++{
			for k:=j+1;k<n;k++ {
				//距离不断地缩小,然后对res进行刷新
				if x :=nums[i]+nums[j]+nums[k];abs(target-x)<path{
					res =x
					//path:用来进行标记,求出来的三数之和到target的距离
					path=abs(target-x)
				}
			}
		}
	}
	return res
}

思路2
外层循环:指针i遍历数组
内层循环:用双指针,寻找sum与target差值绝对值得最小元素
先排序的意义
使用双指针进行缩减遍历范围

func threeSumClosest(nums []int, target int) int {
	result := nums[0] + nums[1] + nums[2]
	sort.Ints(nums)
	for i := 0; i < len(nums)-2; i++ {
		start := i + 1
		end := len(nums) - 1
		for {
			if start < end {
				sum := nums[i] + nums[start] + nums[end]
				if abs(sum-target) < abs(result-target) {
					result = sum
				}
				if sum < target {
					start++
				} else if sum > target {
					end--
				} else {
					return sum
				}
			} else {
				break
			}
		}
	}
	return result
}
func abs(num int) int {
	if num < 0 {
		return -num
	} else {
		return num
	}
}

题目二

三数之和

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
分析
本题总体思路与上题相似,难点是不能包含重复的三元组,这就需要进行双指针的遍历,避免出现重复解

  • 左指针在保证在start<end 的情况下,如果碰到相同的值就让start++实现右移
  • 右指针在保证在start<end 的情况下,如果碰到相同的值就让end–实现左移
    查看题解发现可以对算法进行优化
    在算法中首先对排序后的数组第一个元素进行判断, 如果大于0,则直接break
func threeSum(nums []int) [][]int {
   ans := [][]int{}
   sort.Ints(nums)
   for i := 0; i < len(nums)-2; i++ {
   	if i >= 1 && nums[i] == nums[i-1] {
   		continue
   	}
   	start := i + 1
   	end := len(nums) - 1
   	target := nums[i]
   	for start < end {
   		sum := nums[start] + nums[end]
   		res := []int{nums[i], nums[start], nums[end]}
   		if sum+target == 0 {
   			ans = append(ans, res)
   			for start < end && nums[start] == nums[start+1] {
   				start++
   			}
   			for start < end && nums[start] == nums[end-1] {
   				end--
   			}
   			start++
   			end--
   		} else if sum+target > 0 {
   			end--
   		} else if sum+target < 0 {
   			start++
   		}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值