454. 4Sum II
Given four integer arrays nums1, nums2, nums3, and nums4 all of length n, return the number of tuples (i, j, k, l) such that:
0 <= i, j, k, l < n
nums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
Sol:
class Solution:
def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
hash_map={}
res=0
for x in nums1:
for y in nums2:
hash_map[x+y]=hash_map.get(x+y,0)+1
for x in nums3:
for y in nums4:
test = 0-x-y
if test in hash_map:
res+=hash_map[test]
return res
- Note: 两两组合,变成Two Sum
- O ( n 2 ) , O ( n 2 ) O(n^2), O(n^2) O(n2),O(n2)
================================================
383. Ransom Note
Given two strings ransomNote and magazine, return true if ransomNote can be constructed by using the letters from magazine and false otherwise.
Each letter in magazine can only be used once in ransomNote.Example 1:
Input: ransomNote = “a”, magazine = “b”
Output: false
Example 2:
Input: ransomNote = “aa”, magazine = “aab”
Output: true
Sol:
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
tab = {}
for x in magazine:
tab[x]=tab.get(x,0)+1
for x in ransomNote:
if x not in tab or tab[x]==0:
return False
else:
tab[x]-=1
return True
================================================
15. 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.
Sol:
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums=sorted(nums)#sort first
res=[]
#双指针法
#i,left,right:results x,y,z
for i in range(len(nums)):
if nums[i]>0: #if first >0, no need to check later larger values
return res
if i>0 and nums[i] == nums[i-1]: #去重,和前一个比
continue
left, right = i+1, len(nums)-1
while left<right:
sum3 = nums[i]+nums[left]+nums[right]
if sum3 == 0:
res.append([nums[i], nums[left], nums[right]])
while left<right and nums[right]==nums[right-1]: #去重
right-=1
while left<right and nums[left]==nums[left+1]: #去重
left+=1
right-=1 #记得要走一步:当前值是重复数的最后一个,要走到下一个新数
left+=1
elif sum3>0: #大了,right移动
right-=1
elif sum3<0: #小了,left移动
left+=1
return res
- Note: 哈希法可做但是复杂,双指针法方便
- O ( n 2 ) , O ( 1 ) O(n^2), O(1) O(n2),O(1)
================================================
18. 4Sum
Given an array nums of n integers, return an array of all the unique quadruplets [nums[a], nums[b], nums[c], nums[d]] such that:
0 <= a, b, c, d < n
a, b, c, and d are distinct.
nums[a] + nums[b] + nums[c] + nums[d] == target
You may return the answer in any order.
Sol
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
res = []
for i in range(len(nums)):
if i>0 and nums[i]==nums[i-1]:
continue
for j in range(i+1,len(nums)):
if j>i+1 and nums[j]==nums[j-1]:
continue
left,right=j+1,len(nums)-1
while left<right:
sum4=nums[i]+nums[j]+nums[left]+nums[right]
if sum4==target:
res.append([nums[i],nums[j],nums[left],nums[right]])
while left<right and nums[right] == nums[right-1]:
right-=1
while left<right and nums[left] == nums[left+1]:
left+=1
right-=1
left+=1
elif sum4>target:
right-=1
elif sum4<target:
left+=1
return res
- Note: similar to 3Sum, only fix i,j two loops and remove duplicates for both loops.