454.四数相加II
题目:给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i, j, k, l) 能满足:
0 <= i, j, k, l < nnums1[i] + nums2[j] + nums3[k] + nums4[l] == 0
题目链接/文章讲解/视频讲解:代码随想录
没啥思路....看视频讲解
整体思路:使用哈希表统计 nums1 + nums2 的频率,然后检查 -(nums3 + nums4) 是否存在
map的赋值取值方式要注意,使用set和get

383. 赎金信
题目:给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
如果可以,返回 true ;否则返回 false 。
magazine 中的每个字符只能在 ransomNote 中使用一次。
题目链接/文章讲解:代码随想录
看了下思路,先记录magazine 字母出现的次数,对应ransomNote字母出现做减法,最终没有小于0的即满足条件

15. 三数之和
题目:给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请你返回所有和为 0 且不重复的三元组。
注意:答案中不可以包含重复的三元组。
题目链接/文章讲解/视频讲解:代码随想录
使用哈希法涉及到去重问题,比较麻烦,使用双指针

1. 代码的整体思路
-
排序数组
-
nums.sort((a, b) => a - b) -
排序后,相同的数字会相邻,方便后续去重,同时可以用 双指针 优化搜索。
-
-
外层循环(固定第一个数
nums[i])-
遍历数组,固定
nums[i]作为三元组的第一个数。 -
如果
nums[i] > 0,由于数组已排序,后面的数都更大,不可能再找到nums[i] + nums[j] + nums[k] = 0,直接返回结果。
-
-
内层双指针(寻找
nums[left]和nums[right])-
left = i + 1,right = len - 1,从i的右侧开始向中间搜索。 -
计算
sum = nums[i] + nums[left] + nums[right]:-
如果
sum < 0,说明nums[left]太小,left++(向右移动)。 -
如果
sum > 0,说明nums[right]太大,right--(向左移动)。 -
如果
sum === 0,找到一个有效三元组,加入结果,并跳过重复值。
-
-
2. 去重逻辑详解
(1) 外层循环去重:if (iNum == nums[i - 1]) continue
-
作用:避免
nums[i]重复使用。 -
示例:
-
假设
nums = [-1, -1, 0, 1],排序后仍然是[-1, -1, 0, 1]。 -
当
i = 0,nums[i] = -1,正常处理。 -
当
i = 1,nums[i] = -1,但nums[i] == nums[i - 1](前一个也是-1),所以continue,跳过这个i,避免重复计算[-1, 0, 1]两次。
-
(2) 内层双指针去重:while (left < right && nums[left] == nums[left + 1]) left++
-
作用:跳过
nums[left]的重复值。 -
示例:
-
假设
nums = [-2, 0, 0, 2, 2],当i = 0(nums[i] = -2),left = 1,right = 4。 -
第一次找到
[-2, 0, 2]后:-
nums[left] = 0,nums[left + 1]也是0,所以left++跳过重复的0。 -
nums[right] = 2,nums[right - 1]也是2,所以right--跳过重复的2。
-
-
这样避免重复添加
[-2, 0, 2]多次。
-
eg:
输入:nums = [-1, 0, 1, 2, -1, -4]
排序后:[-4, -1, -1, 0, 1, 2]
外层循环:
i = 0,nums[i] = -4:
left = 1,right = 5
sum = -4 + (-1) + 2 = -3 < 0 → left++
sum = -4 + (-1) + 2 = -3 < 0 → left++(跳过重复的 -1)
sum = -4 + 0 + 2 = -2 < 0 → left++
...(未找到匹配)
i = 1,nums[i] = -1:
left = 2,right = 5
sum = -1 + (-1) + 2 = 0 → 加入结果 [-1, -1, 2]
跳过重复的 left 和 right,left++,right--
sum = -1 + 0 + 1 = 0 → 加入结果 [-1, 0, 1]
i = 2,nums[i] = -1(与前一个 -1 相同,跳过)
i = 3,nums[i] = 0:
left = 4,right = 5
sum = 0 + 1 + 2 = 3 > 0 → right--
不满足 left < right,退出循环
最终结果:[[-1, -1, 2], [-1, 0, 1]]
18. 四数之和
题目:给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):
0 <= a, b, c, d < na、b、c和d互不相同nums[a] + nums[b] + nums[c] + nums[d] == target
你可以按 任意顺序 返回答案 。
题目链接/文章讲解/视频讲解:代码随想录
类比三数之和,使用双指针
在解答过程中遇到的错误:
(1)排序的写法要注意,按顺序从小到大排序sort((a, b) => a - b)
(2)去重的原则
在 i、j、left、right 移动时跳过重复值
(3)j的循环
使用双重 for 循环固定 i 和 j,再用双指针找 left 和 right
整体思路自己写出了,遇到了以上小的错误点导致结果运行失败

有点强度,多看多思考

825

被折叠的 条评论
为什么被折叠?



