18. 4-Sum

Given an array nums of n integers, return an array of the all the unique quadruplets.

Thoughts:

  1. 思路遍历所有数字, 和带target的三数之和相加即可, 有点耗时间复杂度 i.e. O(n3)
  2. 处理细节: 因为排过序, 且遍历的第4位永远放在首位, 所以可以跳过重复的
  3. 将最终target减去第4位, 得到临时target; 然后将 n+1 及之后的数字作为三数之和的数据源; 当然还有第4位数字传入函数即可(只在放结果的时候有用)
  4. 犯错点: 因为之前的三数之和算的是最终结果为0的集合, 导致我加了一个 continue outloop, 忽略了target可能为负数的可能
func fourSum(nums []int, target int) [][]int {
    sort.Ints(nums)
    var ans [][]int
    for i := 0; i < len(nums)-3; i++ {
        if i != 0 && nums[i] == nums[i-1] {
            continue
        }
        threeSum(&ans, nums[i], nums[i+1:], target-nums[i])
    }
    return ans
}

func threeSum(ans *[][]int, ex int, nums []int, target int) {
    length := len(nums)
    // outloop:
    for i := 0; i < length-1; i++ {
        l, r := 0, length-1
        if i != 0 && nums[i] == nums[i-1] {
            l = i - 1
        }
        for l < i && r > i {
            // when target is greater than zero, That won't help
            // if nums[l] > target {
            //     continue outloop
            // }
            if l > 0 && nums[l] == nums[l-1] {
                l++
                continue
            }
            if r < length-1	&& nums[r] == nums[r+1] {
                r--
                continue
            }
            distinguish := nums[l] + nums[i] + nums[r] - target

            if distinguish == 0 {
                *ans = append(*ans, []int{ex, nums[l], nums[i], nums[r]})
                l++
                r--
            } else if distinguish > 0 {
                r--
            } else if distinguish < 0 {
                l++
            }
        }
    }
}

你可能感兴趣的:(算法)