LeetCode 454.四数相加II
题目/视频/文章链接:
454.四数相加||
个人第一时间看法:
考虑到之前做过的两数之和,得用哈希表来解决,只不过对于四个数组的操作有点懵,感觉无从下手,只想到四个for循环暴力解决。
看完代码随想录的想法:
鉴于两数之和的操作,可以将四个数组分成两大组来进行操作,而且这道题不需要考虑重复情况,所以继续用map的结构体。
敲代码时遇到的困难:
满足条件的数组数量应该用前一个大组出现过的次数进行相加,一开始没意识到直接+1了,导致结果数量对应不上。
实际代码:
class Solution(object):
def fourSumCount(self, nums1, nums2, nums3, nums4):
# use a dict to store the elements in nums1 and nums2 and their sum
hashmap = dict()
for n1 in nums1:
for n2 in nums2:
if n1 + n2 in hashmap:
hashmap[n1+n2] += 1
else:
hashmap[n1+n2] = 1
# if the -(a+b) exists in nums3 and nums4, we shall add the count
count = 0
for n3 in nums3:
for n4 in nums4:
key = - n3 - n4
if key in hashmap:
count += hashmap[key]
return count
LeetCode 383. 赎金信
题目/视频/文章链接:
383.赎金信
个人第一时间看法:
这和之前做过的字母异位词大同小异,直接用数组的结构来解题即可
看完代码随想录的想法:
这就是一道最基础的哈希表操作题
敲代码时遇到的困难:
没什么难度,能敲出字母异位词的代码,这道题也不在话下
实际代码:
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
arr = [0] * 26
for x in magazine: # 记录 magazine里各个字符出现次数
arr[ord(x) - ord('a')] += 1
for x in ransomNote: # 在arr里对应的字符个数做--操作
if arr[ord(x) - ord('a')] == 0: # 如果没有出现过直接返回
return False
else:
arr[ord(x) - ord('a')] -= 1
return True
题目/视频/文章链接:
15.三数之和
个人第一时间看法:
懵逼,三个数没办法像之前的四数相加分成两个大组来解题,而且还不能重复,想到set结构体可以不重复,但是三个数该咋用set来遍历呢,挠挠头
看完代码随想录的想法:
既然不需要返回下标,那就可以先进行排序,进而这道题最适方法不是用哈希表,而是用双指针的方法来进行操作,一个从头开始遍历,后两个从两边进行遍历,分清楚什么情况下该移动哪个指针,然后这三个指针都需要进行去重操作,这是个重难点。
敲代码时遇到的困难:
在从头遍历的那个指针进行去重操作时,出现了差错,应该将当前指针的位置与前一个位置进行对比去重,若是对后一个进行对比的话容易漏掉可行结果。
实际代码:
class Solution:
def threeSum(self, nums):
ans = []
n = len(nums)
nums.sort()
# 找出a + b + c = 0
# a = nums[i], b = nums[left], c = nums[right]
for i in range(n):
left = i + 1
right = n - 1
# 排序之后如果第一个元素已经大于零,那么无论如何组合都不可能凑成三元组,直接返回结果就可以了
if nums[i] > 0:
break
if i >= 1 and nums[i] == nums[i - 1]: # 去重a
continue
while left < right:
total = nums[i] + nums[left] + nums[right]
if total > 0:
right -= 1
elif total < 0:
left += 1
else:
ans.append([nums[i], nums[left], nums[right]])
# 去重逻辑应该放在找到一个三元组之后,对b 和 c去重
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 ans
题目/视频/文章链接:
18.四数之和
个人第一时间看法:
基于四数相加和三数之和的思路,既然不需要返回下标,那就可以先排序,进而可以运用双指针,在三个指针的基础上,再在左端加一个指针,前两个为一组,后两个为一组进行操作,挨个遍历从而实现四数之和应该就可以。
看完代码随想录的想法:
只不过这道题给的要求不是0而是target,这样的话在开头判断的时候就有更多的细节了,不只是去重还得剪枝,需要好好琢磨。
敲代码时遇到的困难:
在开头的剪枝操作有点生疏,再就是第二个指针要在第一个指针的基础上进行剪枝去重,得多加熟练才行。
实际代码:
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
nums.sort()
n = len(nums)
res = []
for i in range(n):
if i > 0 and nums[i] == nums[i - 1]: continue # 对nums[i]去重
for k in range(i+1, n):
if k > i + 1 and nums[k] == nums[k-1]: continue # 对nums[k]去重
p = k + 1
q = n - 1
while p < q:
if nums[i] + nums[k] + nums[p] + nums[q] > target: q -= 1
elif nums[i] + nums[k] + nums[p] + nums[q] < target: p += 1
else:
res.append([nums[i], nums[k], nums[p], nums[q]])
# 对nums[p]和nums[q]去重
while p < q and nums[p] == nums[p + 1]: p += 1
while p < q and nums[q] == nums[q - 1]: q -= 1
p += 1
q -= 1
return res
今日收获:
今天第一道题也是运用了map的结构进行操作,整体的思路就是看看能不能构成两个组,从而进行哈希表操作解题,第二题就是跟之前的题目进行变式训练而已,熟练操作,第三四题巧妙的运用题目要求,进行排序从而可以使用双指针法进行解题,而且其中的剪枝去重操作格外需要注意细节,仍需多多磨练!今日学习时长2h!