本系列文章是我刷代码随想录过程中的笔记。代码地址:leetcode
今天是我刷“代码随想录”的第六天
今日内容
- 454.四数相加II
- 383.赎金信
- 15.三数之和
- 18.四数之和
- 总结
leetcode 454. 四数相加 II
这道我们两两分组,先计算nums1与nums2的和,并使用dict记录,然后再nums3和nums4中判断是否出现过。如果出现过,记录的次数就加上nums1与nums2的和出现的次数。
class Solution:
def fourSumCount(self, nums1: List[int], nums2: List[int], nums3: List[int], nums4: List[int]) -> int:
dic = dict()
count = 0
for i in nums1:
for j in nums2:
s = i + j
if s in dic:
dic[s] += 1
else:
dic[s] = 1
for i in nums3:
for j in nums4:
s = 0 - i - j
if s in dic:
count += dic[s]
return count
leetcode 383. 赎金信
这道题与昨天的异位字符串相同,先记录下两个字符串中字符出现的个数。然后遍历较短的字符串生成的shortDict,当在longDict中找不到短的字母或者出现的次数小于短的个数时,说明无法构成该短的字符串,返回false。
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
shortDic = dict()
longDic = dict()
for i in ransomNote:
if i in shortDic:
shortDic[i] += 1
continue
shortDic[i] = 1
for i in magazine:
if i in longDic:
longDic[i] += 1
continue
longDic[i] = 1
for k, v in shortDic.items():
if k not in longDic or v > longDic[k]:
return False
return True
leetcode 15. 三数之和
这道题的难点在于如何去重。首先使用for循环固定一个值nums[i],然后对剩余的元素使用双指针法。
- 注意点一:如果nums[i] > 0的话,剩下的元素不会再比0小了,这时候可以直接返回result
- 注意点二:如果碰到两个连续元相同,那么需要去重,即直接跳过。
再往结果中添加元素的时候,注意如果左右指针也存在相同的元素,也需要跳过。以保证结果的唯一性。
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
nums.sort()
n = len(nums)
result = []
for i in range(n):
if nums[i] > 0:
return result
if i > 0 and nums[i] == nums[i - 1]:
continue
left = i + 1
right = n - 1
while left < right:
s = nums[i] + nums[left] + nums[right]
if s >0 :
right -= 1
if s < 0:
left += 1
if s == 0:
result.append([nums[i], nums[left], nums[right]])
while left != right and nums[left] == nums[left + 1]:left += 1
while left != right and nums[right] == nums[right - 1]:right -= 1
left += 1
right -= 1
return result
leetcode 18. 四数之和
这道题与三数之和一样,但是需要固定两个值,去重两次。
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
n = len(nums)
result = []
for i in range(n):
if i > 0 and nums[i] == nums[i - 1] : continue # 对i去重
for j in range(i + 1, n):
if j > i + 1 and nums[j] == nums[j - 1]: continue # 对j去重
l = j + 1
r = n - 1
while l < r:
s = nums[i] + nums[j] + nums[l] + nums[r]
if s > target:
r -= 1
if s < target:
l += 1
if s == target:
result.append([nums[i], nums[j],nums[l], nums[r]])
while l < r and nums[l] == nums[l + 1]:l += 1
while l < r and nums[r] == nums[r - 1]:r -= 1
l += 1
r -= 1
return result
总结
今天是哈希表的最后一天。哈希表的题主要是思路不好想。如果想到了,那么基本上就是秒杀。我在这方面的思路还比较欠缺。需要进一步的练习。