将三数和,转换成n个两数和问题求解。时间O(n^2), 空间O(n)。
以排序后的元组作为集合元素,自带去重效果。
用取值的剩余次数来避免重复取值,和避免多次出现的值的漏选。
class Solution:
    def threeSum(self , num: List[int]) -> List[List[int]]:
        h_num = {}                # 构建哈希表,键为数值,值为数值出现的次数
        for n in num:
            if not h_num.get(n):
                h_num[n] = 1
            else:
                h_num[n] += 1
        # 用集合存结果,可以去重
        h_result = set() 
        # 转换成两数和问题求解
        for a in h_num:           # 在a已知时,b+c = -a 为两数和问题
            h_num[a] -= 1         # 取了一个为a,该值次数减少一个,避免后面重复取值
            for b in h_num:   
                if h_num[b] >0:           # 如果该数在上一层没有被取或者没有被取完,则取为b
                    h_num[b] -= 1         # 取了一个为b,该值次数减少一个,避免后面重复取值
                    if h_num.get(-a-b):   # 检查c=-a-b是否在哈希表内
                        if h_num[-a-b]>0: # 如果该数在上一层没有被取或者没有被取完,则取为c
                                          # 排序后以元组的形式存入集合中,自带去重效果
                            h_result.add(tuple(sorted([a, b, -a-b])))
                    h_num[b] += 1         # 在下一轮取值前,恢复原状
            h_num[a] += 1                 # 在下一轮取值前,恢复原状
        # 由于a,b,c的任意性,存下的结果就是最终结果
        return [list(res) for res in h_result]