Lever's Castle

15. 三数之和

December 13, 2019

https://leetcode-cn.com/problems/3sum/

使用语言:Go

func threeSum(nums []int) [][]int {
    var res [][]int
    if len(nums) < 3 {
        return res
    }
    set := make(map[int]int)
    flag := make(map[int]map[int]bool)
    for _, num := range nums {
        set[num]++
        flag[num] = make(map[int]bool)
    }
    for num1 := range set {
        set[num1]--
        for num2, count2 := range set {
            if count2 == 0 || flag[num1][num2] {
                continue
            }
            set[num2]--
            num3 := 0 - num1 - num2
            count3 := set[num3]
            if count3 > 0 {
                res = append(res, []int{num1, num2, num3})
                flag[num1][num2] = true
                flag[num1][num3] = true
                flag[num2][num1] = true
                flag[num2][num3] = true
                flag[num3][num1] = true
                flag[num3][num2] = true
            }
            set[num2]++
        }
        set[num1]++
    }


    return res
}

三数之和要求等于 0,我们只要确定两个数,第三个数其实也就确定了,所以我们只需要遍历前两个数的全部组合,并找到其中第三个数也存在的情况即可。我在这里用 set 存放了 nums 中的所有值,并记录了每个值出现的次数,用 flag 记录已经存过得三数组合,以防止出现重复的情况。

在遍历的时候,我动态的修改了 set 中 num1 和 num2 的次数,来保证 num1,num2,num3 都能出现在 nums 中,在循环结束之后再恢复 num1 和 num2 的计数。遍历 set 还带来一个好处是当 nums 中存在的重复项很多的时候,可以减少一些不必要的重复。


Lever

痕迹
没有过去,就没法认定现在的自己