Leetcode454
题目:四数相加II
学习资料:代码随想录
初始思路
- 分两次遍历,AB一组,CD一组,看AB的和是否等于负的CD和
- 利用哈希方法,使用dict,需要统计出现过的次数
学习后:
- 思路基本一致,学习后逻辑更为清楚。
- 注意count要加key的value
实现过程:
re = dict()
for n1 in nums1:
for n2 in nums2:
if n1+n2 not in re:
re[n1+n2] = 1
else:
re[n1+n2] +=1
count = 0
for n3 in nums3:
for n4 in nums4:
if -(n3+n4) in re:
count += re[-(n3+n4)]
return count
Leetcode383
题目:赎金信
学习资料:代码随想录
初始思路
- 利用dict来构建hash函数,然后value计算count
学习后
- 因为都是小写字母,可以利用数组来存储;
- 只要ransom的字符在record中等于0了,那么就说明不能。
实现过程
思路一:
re = dict()
for i in ransomNote:
if i in re:
re[i] += 1
else:
re[i] = 1
for i in magazine:
if i in re:
re[i] -= 1
for i in re:
if re[i] > 0:
return False
return True
思路二:
re = [0] *26
for i in magazine:
re[ord(i)-ord("a")] += 1
for i in ransomNote:
if re[ord(i)-ord("a")] == 0:
return False
else:
re[ord(i)-ord("a")] -= 1
return True
Leetcode 15
题目:三数之和
学习资料:代码随想录
初始思路
- 使用hash的方法,但是去重逻辑比较复杂
学习后
- 返回的是三元组,没有要求返回下标,所以可以先排序
- 双指针的方法,首先i遍历,代表a;left为i+1位置,代表b;right为末尾,代表c;因为已经排序,所以判断,如果当a+b+c>0时,移动right;当小于0时,移动left;
- 去重部分,对于a而言,要判断当前和前一个元素是否有重复,如果重复就pass;
- 对于b,c而言就是不需要在大于或小于0的时候去重,因为这时候left和right都要进行移动;这部分去重可以放在等于的过程中。
nums.sort()
re = []
for i in range(len(nums)):
#排序后如果第一个大于0,则不可能满足条件
if nums[i] > 0 and i ==0 :
break
# 如果元素和前一个一样,则直接pass,进行去重
if i > 0 and nums[i] == nums[i-1]:
continue
l = i + 1
r = len(nums) -1
while l < r:
if nums[l] + nums[r] == - nums[i]:
re.append([nums[i],nums[l],nums[r]])
l += 1
r -= 1
while l < r and nums[l] == nums[l-1]:
# 与前面一个比较
l += 1
while l < r and nums[r] == nums[r+1]:
# 从后向前,同样也是和之前的比较
r -= 1
elif nums[l] + nums[r] > - nums[i]:
r -= 1
else:
l += 1
return re
Leetcode18
题目:四数之和
学习资料:代码随想录
初始思路
- 还是利用上面相似的思路,不过要注意剪枝的条件,多加一次循环
学习后:
- 重点还是在去重的判断上,这次是target不要判断错;对于第二个数字剪枝的时候,也要注意是大于i+1之后
实现过程
nums.sort()
n = len(nums)
re = []
for i in range(n):
if nums[i] > target and nums[i] >= 0:
break
if nums[i] == nums[i-1] and i > 0 :
continue
for k in range(i+1, n):
if nums[k] == nums[k-1] and k > i+1:
continue
l = k + 1
r = n - 1
while l < r :
if nums[i] + nums[k] + nums[l] + nums[r] == target:
re.append([nums[i],nums[k],nums[l],nums[r]])
l += 1
r -= 1
while l < r and nums[l] == nums[l-1]:
l += 1
while l < r and nums[r] == nums[r+1]:
r -= 1
elif nums[i] + nums[k] + nums[l] + nums[r] > target:
r -= 1
else:
l += 1
return re
总结
- 注意 去重的逻辑,不是很容易想好,后两道题思路基本一致
- 类似数组内部求和思想基本一致