1. 4Sum II (Leetcode Number: 454)
Create two empty dictionaries dic_a and dic_b -> get the sum value of different single nums1 and nums2 elements, store the sum in dic_a as the key and the times of getting this sum as the respective value -> repeat last step for dic_b (nums3 and nums4) -> create a target variable equals to 0 - dic_[key] -> try to find if target is in dic_a, if yes return the multiplication value of dic_a[-dic_b[key]] and dic_b[key], store the result in total_count -> repeat last step for all keys in dic_b and add all results up, which is the final value of total_count
class Solution:
def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
dic_a = {}
dic_b = {}
for i in range(len(nums1)):
for j in range(len(nums2)):
sum_a = nums1[i] + nums2[j]
if sum_a in dic_a:
dic_a[sum_a] += 1
else:
dic_a[sum_a] = 1
for k in range(len(nums2)):
for l in range(len(nums3)):
sum_b = nums3[k] + nums4[l]
if sum_b in dic_b:
dic_b[sum_b] += 1
else:
dic_b[sum_b] = 1
total_count = 0
for key in dic_b:
target = 0 - key
if target in dic_a:
total_count += dic_a[target] * dic_b[key]
return total_count
2. Ransom Note (Leetcode Number: 383)
This question is similar to Q1, the dic_r derived from ransomNote is the subdictionary of dic_m derived from magazine
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
dic_r = {}
dic_m = {}
for letter_r in ransomNote:
if letter_r in dic_r:
dic_r[letter_r] += 1
else:
dic_r[letter_r] = 1
for letter_m in magazine:
if letter_m in dic_m:
dic_m[letter_m] += 1
else:
dic_m[letter_m] = 1
for key_r in dic_r:
if key_r not in dic_m or dic_r[key_r] > dic_m[key_r]:
return False
return True
3. 3Sum (Leetcode Number: 15)
a. The main function is to sort the input list nums and iterate through the array and avoid duplicates of nums[i] in the output by applying this conditional statement
if i == 0 or nums[i - 1] != nums[i]:
b. the sum_fun function is to find valid nums[i], nums[left] and nums[right] that the sum of those three elements equals to 0. By applying the following conditional statement as well the conditional statement mentioned above, the combination of all three elements would be unique.
while left < right and nums[left] == nums[left - 1]:
left += 1
Final code
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
res = []
nums.sort()
for i in range(len(nums)):
if nums[i] > 0:
break
if i == 0 or nums[i - 1] != nums[i]:
self.sum_fun(nums, i, res)
return res
def sum_fun(self, nums , i, res):
left, right = i + 1, len(nums) - 1
while (left < right):
total = nums[i] + nums[left] + nums[right]
if total < 0:
left += 1
elif total > 0:
right -= 1
else:
res.append([nums[i], nums[left], nums[right]])
left += 1
right -= 1
while left < right and nums[left] == nums[left - 1]:
left += 1
4. 4Sum (Leetcode Number: 18)
The solution is similar to 3Sum, add one more pointer and take extra care of the boundaries.
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
res = []
nums.sort()
for i in range(len(nums)):
if i == 0 or nums[i] != nums[i - 1]:
for k in range(i + 1, len(nums)):
if k == i + 1 or nums[k] != nums[k-1]:
self.sum_fun(nums, i, k, res, target)
return res
def sum_fun(self, nums , i, k, res, target):
left, right = k + 1, len(nums) - 1
while (left < right):
total = nums[i] + nums[k] + nums[left] + nums[right]
if total < target:
left += 1
elif total > target:
right -= 1
else:
res.append([nums[i], nums[k], nums[left], nums[right]])
left += 1
right -= 1
while left < right and nums[left] == nums[left - 1]:
left += 1