解題思路
最開始是打算沿著二數之和的思路做,即固定了最大的,然后小的開始遍歷,因為這種遍歷方式只需要遍歷一輪就能完成,所以復雜度應該是O(n2),但是最后幾個示例還是超時了,可能進一步優化還是可以做的。但是事實上,我最開始就在尋找一個能夠約束剩余兩個變量的方法,因為不重復我們可以添加大小關系的假設,但是腦子里一直是兩個指針在一個遍歷中移動所以沒搞出來。事實上是,一個變量變大,另一個變量的上限減小,可以基于這個想法做。
未AC代碼,最后樣例超時
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:def get_res(index, k):disk = {}res = []for i, n in enumerate(nums[:index]):if n <= - k // 2:if n == -k // 2 and n in disk and n + n + k == 0:res.append([n, n, k]) disk[-k - n] = ielse:if n in disk:res.append([n, - n - k, k])return resres = []nums.sort()for i in range(-1, -len(nums) - 1, -1):temp = get_res(i, nums[i])for t in temp:if t not in res:res.append(t)return res
官方題解
class Solution:def threeSum(self, nums: List[int]) -> List[List[int]]:n = len(nums)nums.sort()ans = list()# 枚舉 afor first in range(n):# 需要和上一次枚舉的數不相同if first > 0 and nums[first] == nums[first - 1]:continue# c 對應的指針初始指向數組的最右端third = n - 1target = -nums[first]# 枚舉 bfor second in range(first + 1, n):# 需要和上一次枚舉的數不相同if second > first + 1 and nums[second] == nums[second - 1]:continue# 需要保證 b 的指針在 c 的指針的左側while second < third and nums[second] + nums[third] > target:third -= 1# 如果指針重合,隨著 b 后續的增加# 就不會有滿足 a+b+c=0 并且 b<c 的 c 了,可以退出循環if second == third:breakif nums[second] + nums[third] == target:ans.append([nums[first], nums[second], nums[third]])return ans