###### tags: `Leetcode` `medium` `pointer` `python` `Top 100 Liked Questions` # 15. 3Sum ## [題目連結:] https://leetcode.com/problems/3sum/ ## 題目: Given an integer array nums, return all the triplets ```[nums[i], nums[j], nums[k]]``` such that ```i != j, i != k,``` and ```j != k```, and ```nums[i] + nums[j] + nums[k] == 0```. Notice that the solution set must not contain duplicate triplets. **Example 1:** ``` Input: nums = [-1,0,1,2,-1,-4] Output: [[-1,-1,2],[-1,0,1]] Explanation: nums[0] + nums[1] + nums[2] = (-1) + 0 + 1 = 0. nums[1] + nums[2] + nums[4] = 0 + 1 + (-1) = 0. nums[0] + nums[3] + nums[4] = (-1) + 2 + (-1) = 0. The distinct triplets are [-1,0,1] and [-1,-1,2]. Notice that the order of the output and the order of the triplets does not matter. ``` Example 2: ``` Input: nums = [0,1,1] Output: [] Explanation: The only possible triplet does not sum up to 0. ``` Example 3: ``` Input: nums = [0,0,0] Output: [[0,0,0]] Explanation: The only possible triplet sums up to 0. ``` ## 解題想法: 兄弟題目: [16. 3Sum Closest](/-2KGuo22S3qNrqbNTpvC_w)、[18. 4Sum](/DxMPstejSjGGRPi7EHckdA) * 題目要求: 給一數組,要求三數和=0,且每種組合不能重複 * use two pointer * for 迴圈固定一值(i) * 找two pointer(j、k)與i之nums[i]+nums[j]+nums[k]=0 * j=i+1 * k=len(nums) * 因為避免找重複的組合,所以**數組一定要先排序**!! * 優化:因為是排序好再找,因此nums[i]一定是最小值,若nums[i]>0,則一定沒解了,因為nums[j]、nums[k]一定更大,可直接break ## python: time:O(nlongn+n^2) space:O(1) ``` python= class Solution(object): def threeSum(self, nums): """ :type nums: List[int] :rtype: List[List[int]] """ #use two pointer res =[] #一定要先排序 nums.sort() for i in range(len(nums)-2): #和為0 sort完 jk在i後面 若i都>0了 肯定沒搞頭了 if nums[i]>0: break #若遇重複i,只能使用第一次出現的 所以跳過此輪 #因為確保i=0與i=1時nums[i]相同值時 要優先用i=0 所以要規定判別於i>0 if i>0 and nums[i]==nums[i-1]: continue j = i+1 k = len(nums)-1 while j<k: #nums之i+j+k值為0 fuck ya if nums[i]+nums[j]+nums[k]==0: res.append([nums[i],nums[j],nums[k]]) j+=1 k-=1 #跳過重複的nums[j] while j<k and nums[j]==nums[j-1]: j+=1 #跳過重複的nums[k] while j<k and nums[k]==nums[k+1]: k-=1 #總值過小 增加j elif nums[i]+nums[j]+nums[k]<0: j+=1 #總值過大 減k else: k-=1 return res if __name__ == '__main__': result = Solution() nums = [-1,0,1,2,-1,-4] ans = result.threeSum(nums) print(ans) ```