454. 四数相加 II - 力扣(LeetCode)
1. 文章链接
2. 看到题目的第一想法
来自四个数组的四个元素相加等于0, 找这四个元素分别在这四个数组的下角标。
数组长度都为200以内,所以也可以。
那我们前两个元素就用for循环来搜,得到前两个元素的和。
然后剩下的一定是。
于是我们可以为后面这两个元素做一个长的字典,键=两个元素的和,值为两个元素的下角标组成的列表。
但是这里有个问题就是两个元素的和可能相同,但是角标列表不一致。
3. 看完代码随想录之后的想法
我们要明确我们的目标,不是要输出四个角标组成的元组。
而是要返回总共有多少个元组,所以我们的value其实就可以存有多少种不一致的角标列表就可以,而不是直接存角标列表。
4. 实现过程中遇到的困难
碰到hash table的问题,python果断用dict, dict.get()等方法,不要犹豫,各种其他的Python的hash table感觉也没啥用,徒增烦恼。
5. 学习时长
30分钟
383. 赎金信 - 力扣(LeetCode)
1. 文章链接
2. 看到题目的第一想法
当然是将magazine中所有的字符,按照{字符: 在杂志中的出现次数}统计。
然后遍历ransomNote中每一个字符,出现在hash table中的,且value不是0的,就给对应value-1。如果value是0,那就返回False.
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
hash_dict = dict()
for char in magazine:
hash_dict[char] = hash_dict.get(char, 0) + 1
for char in ransomNote:
times = hash_dict.get(char, 0)
if times <= 0:
return False
else:
hash_dict[char] = hash_dict.get(char, 0) - 1
return True
3. 实现过程中遇到的困难
无
4. 看完代码随想录之后的想法
可以用数组,会更省空间
5. 学习时长
20分钟
15. 三数之和 - 力扣(LeetCode)※(difficult)
1. 文章链接
2. 看到题目的第一想法
3 <= nums.length <= 3000意味着前两个数字用for循环,应该不太行。
3. 实现过程中遇到的困难
哈希表应该不能做这道题,因为最低要构建第三个数字的set, 前两个数字用求和,这个太费时间了。
况且数组中存在值相等元素,set就没办法应对。
4. 看完代码随想录之后的想法
排序。
双指针。
用i遍历数组,i右侧两个指针left和right。
去重,
- 因为
i前后相邻可能遍历多次相等的元素,所以nums[i]一定要和nums[i-1]进行比较。 - left和right也要去重,所以要比较
nums[left]==nums[left-1]以及nums[right]==nums[right+1]。
class Solution:
def threeSum(self, nums: List[int]) -> List[List[int]]:
result = []
nums.sort()
for i in range(len(nums) - 2):
if nums[i] > 0:
return result
if (i > 0) and (nums[i] == nums[i - 1]):
continue
sum_last_two = 0 - nums[i]
left = i + 1
right = len(nums) - 1
while left < right:
sum_value = nums[i] + nums[left] + nums[right]
if sum_value > 0:
right -= 1
if sum_value < 0:
left += 1
if sum_value == 0:
result.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
left += 1
right -= 1
return result
过程中需要注意的是,如果sum_value==0的情况下,需要两边同时收缩,而不是不动了,不然就会死循环。
5. 学习时长
40分钟
18. 四数之和 - 力扣(LeetCode)
1. 文章链接
2. 看到题目的第一想法
和三数之和应该使用同样的思路,只不过不是只遍历一个i,而是外侧需要i,j双层循环。
class Solution:
def fourSum(self, nums: List[int], target: int) -> List[List[int]]:
result = []
nums.sort()
for i in range(len(nums) - 3):
if (nums[i] >= target) and (target > 0):
break
if (i > 0) and (nums[i] == nums[i - 1]):
continue
for j in range(i + 1, len(nums) - 2):
if (target > 0) and (nums[i] + nums[j] >= target):
break
if (j > (i + 1)) and (nums[j] == nums[j - 1]):
continue
left = j + 1
right = len(nums) - 1
while left < right:
sum_int = nums[i] + nums[j] + nums[left] + nums[right]
if sum_int < target:
left += 1
if sum_int > target:
right -= 1
if sum_int == target:
result.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
return result
3. 实现过程中遇到的困难
内层循环如果出现比target大且target为正的情况,不应该立刻就return,这样外层循环也会终止,容易丢失此后的结果。
4. 看完代码随想录之后的想法
思想跟三数之和差不多,就是需要额外注意一些细微的剪枝条件。
5. 学习时长
30分钟。