题目链接
https://leetcode-cn.com/problems/3sum/
解法思路
先对数组进行排序,排序完之后对数组进行遍历,每遍历一个元素设置左右两个指针,左指针指向当前元素的下一个元素,右指针指向数组最后一个元素,然后对当前元素,左指针指向元素,右指针指向元素进行相加,如果相加的和大于0,则将右指针左移(减少总和),如果小于0,则将左指针右移(增大总和),如果等于0,则当前元素、左指针元素、右指针元素满足题目要求。
但是一个元素可能有多种组合满足题目要求,如:[-2, 0, 1, 1, 1, 1, 2],遍历到2时,满足=0的结果集有[-2, 1, 1]和[-2, 0, 2]有两个解,但是按我们以上的逻辑只是移动左右指针求和,[-2, 1, 1]这个答案会出现两次,这样子答案就会出现重复值,所以我们要做一层过滤,如果左指针元素和左指针右边元素值相等(即nums[left] == nums[left + n]),则将左指针持续右移,同理,右指针元素如果和右指针左边元素相等(即nums[right] == nums[right - 1]),则将右指针持续左移。
解法代码
func threeSum(nums []int) [][]int {length := len(nums)var result [][]intif length < 3 {return result}// 排序quickSort(nums, 0, length-1)var left, right intfor i := 0; i < length-1; i++ {// 相同组合的跳过if i > 0 && nums[i] == nums[i-1] {continue}// 左右指针所在位置left, right = i+1, length-1for left < right {sum := nums[i] + nums[left] + nums[right]if sum > 0 {right--} else if sum < 0 {left++} else {item := []int{nums[i], nums[left], nums[right]}result = append(result, item)for left < right && nums[left] == nums[left + 1] {left++}if left < right && nums[right] == nums[right - 1] {right--}left++right--}}}return result}func quickSort(sortArray []int, left, right int) {if left < right {pos := partition(sortArray, left, right)quickSort(sortArray, left, pos-1)quickSort(sortArray, pos+1, right)}}func partition(sortArray []int, left, right int) int {key := sortArray[right]i := left - 1for j := left; j < right; j++ {if sortArray[j] <= key {i++sortArray[i], sortArray[j] = sortArray[j], sortArray[i]}}sortArray[i+1], sortArray[right] = sortArray[right], sortArray[i+1]return i + 1}
