三数之和

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

示例 2:

输入:nums = []
输出:[]

示例 3:

输入:nums = [0]
输出:[]

提示:

0 <= nums.length <= 3000
-105 <= nums[i] <= 105

注:题目来源于力扣

超暴力解题思路

三数之和,可以看作是固定一个值,求解剩下两个数----双指针。先对数组进行排序(双指针),当符合条件的时候,组装数组,并判断是否出现重复值。如果不重复则加入结果中。

代码

func threeSum(nums []int) [][]int {

	if len(nums)<=2{
		return nil
	}
	result := make([][]int,0)
	sort.Ints(nums)
	for i:=0;i<len(nums);i++{
		tmp := 0-nums[i]
		log.Println(tmp)
		x := 0
		y := len(nums)-1
		for x<y {
			if x == i{
				x++
				continue
			}
			if y==i {
				y--
				continue
			}
			if nums[x]+nums[y] < tmp {
				x++
			}else if nums[x] + nums[y] > tmp {
				y--
			}else if nums[x] + nums[y] == tmp {
				tmpArr := []int{nums[i],nums[x],nums[y]}
				sort.Ints(tmpArr)
				if !dupRemove(result,tmpArr) {
					result =  append(result,tmpArr)
				}
				x++
				y--
			}

		}
	}
	return result
}

// 查重
func dupRemove(result [][]int,tmp []int)bool{
	for i:=0;i<len(result);i++{
		count := 0
		for j:=0;j<len(result[i]);j++{
			if result[i][j] == tmp[j] {
				count++
			}
			if count == len(tmp) {
				return true
			}
		}
	}
	return false
}

正确解法

上面的解法是对的,但是输在了去重这部分。最后一根稻草竟然是去重。哈,安排(双指针遍历之前的操作)。

  • 对数组进行排序。双指针需得对数组进行排序,然后对数组进行排序能够避免回头查找,实现线性查找
  • 遍历排序后的数组
    • 如果nums[i] > 0,立即跳出循环。因为数组是按照从小到大排序的,如果nums[i]>0,则后面就没有负数,使得nums[i] + nums[i+1]+nums[i+2] = 0
    • 对于重复的元素,跳过。假设数组中的三个数为:a,b,c。又因为a<=b<=c,则我们只要对a和b遍历去重就可以避免找到结果集之后还需要查重。a的遍历从1开始就考虑是否重复,b的遍历要从i+1(假设a的下表为i)就要考虑是否重复了。b不能从0开始重复,因为会出现:-1 -1 0 1 2中不能找出-1 -1 2。

代码

func threeSum(nums []int) [][]int {

	if len(nums)<=2{
		return nil
	}
	result := make([][]int,0)
	sort.Ints(nums)
	for i:=0;i<len(nums);i++{
		if nums[i] > 0 {
			return result
		}
		if i>0 && nums[i] == nums[i-1] {
			continue
		}
		tmp := 0-nums[i]
		x := i + 1
		y := len(nums)-1
		for x<y {
			// 如果这里的x只是大于零的话,可能就会出现一种情况就是查到了a的枚举 -1 -1 0 1 2 就会吞掉:-1 -1 2的情况
			if x>i+1 && nums[x] == nums[x-1] {
				x++
				continue
			}
			if y>=0 && y<len(nums)-1 && nums[y] == nums[y+1] {
				y--
				continue
			}
			if nums[x]+nums[y] < tmp {
				x++
			}else if nums[x] + nums[y] > tmp {
				y--
			}else if nums[x] + nums[y] == tmp {
				tmpArr := []int{nums[i],nums[x],nums[y]}
				result =  append(result,tmpArr)
				x++
				y--
			}
		}
	}
	return result
}

上一篇:Java异常分类


下一篇:List集合中根据指定个数进行分组,找出分组的和与目标值最接近的组合