代码随想录算法训练营Day07| 454. 四数相加Ⅱ 383.赎金信 15.三数之和 18.四数之和
454.四数相加Ⅱ
先看了视频,理解之后做出来的
1 var fourSumCount = function(nums1, nums2, nums3, nums4) { 2 let map = new Map(); 3 for (let a = 0; a < nums1.length; a++) { 4 for (let b = 0; b < nums2.length; b++) { 5 6 let value = map.has(nums1[a] + nums2[b]) ? map.get(nums1[a] + nums2[b]) + 1 : 1; 7 map.set(nums1[a] + nums2[b], value); //是否已有这个键,有则value+1,无则传入value为1; 8 } 9 } 10 let count = 0; //用于储存,有多少个符合条件的元组 数量 11 for (let c = 0; c < nums3.length; c++) { 12 for (let d = 0; d < nums4.length; d++) { 13 for (const [Key, value] of map.entries()) { //遍历并读取map中的键值对 14 if (Key === -(nums3[c] + nums4[d])) { 15 count += value; 16 } 17 } 18 } 19 } 20 return count; 21 };
注意:
1.map.entries() – returns an iterable for entries [key, value], it’s used by default in for..of.
2. 三元条件运算符中,不可以使用自增运算符(++),例如
1 map.has(nums1[a] + nums2[b]) ? map.get(nums1[a] + nums2[b]) + + : 1; 2 // 是错误的
不管是 前置(++map.get(nums1[a] + nums2[b])),还是后置(map.get(nums1[a] + nums2[b])++),因为三目条件运算符中没有其它运算,所以返回的依旧只是map.get(nums1[a] + nums2[b])的值,并无改变。
关于操作符前置和后置,不是什么情况下都可以用的,具体解释可以参考该篇文章:https://juejin.cn/post/7042101620380794917
383.赎金信
这题比较简单,思考步骤,以及代码如下:
1 /** 2 * @param {string} ransomNote 3 * @param {string} magazine 4 * @return {boolean} 5 */ 6 var canConstruct = function(ransomNote, magazine) { 7 let mapA = new Map(); 8 // 在mapA中存储ransomNote的所有字符,字符为key,出现次数为value; 9 for (let letter of ransomNote) { 10 if (mapA.has(letter)) { 11 mapA.set(letter, mapA.get(letter) + 1); 12 } else { 13 mapA.set(letter, 1) 14 } 15 } 16 // 遍历magazine,如果mapA中存在该字符,则对应的value-1 17 for (let letter of magazine) { 18 if (mapA.has(letter)) { 19 mapA.set(letter, mapA.get(letter) - 1); 20 } 21 } 22 // 遍历mapA,如果mapA中存在该字符的value > 0,则说明有字符不能由magazine中的字符构成,直接返回false 23 for (const [key, value] of mapA.entries()) { 24 if (value > 0) { 25 return false; 26 } 27 } 28 // 否则,返回true 29 return true; 30 };
15.三数之和
先看视频,再自己做出来
方法:双指针法
1 /** 2 * @param {number[]} nums 3 * @return {number[][]} 4 */ 5 var threeSum = function(nums) { 6 // 首先,进行排序 7 //nums.sort(); 8 nums.sort((a, b) => a - b) 9 let arr = new Array(); 10 for (let i = 0; i < nums.length; i++) { 11 if (nums[i] > 0) return arr; //如果最小的数>0,则不可能有=0的三数之和,直接返回false 12 if (i > 0 && nums[i] === nums[i - 1]) { continue; } 13 let left = i + 1; 14 let right = nums.length - 1; 15 while (right > left) { 16 if (nums[left] + nums[right] + nums[i] > 0) right--; 17 else if (nums[left] + nums[right] + nums[i] < 0) left++; 18 else { 19 arr.push([nums[i], nums[left], nums[right]]); 20 // 开始去重 21 while (left < right && nums[left] === nums[left + 1]) { 22 left += 1; 23 } 24 while (left < right && nums[right] === nums[right - 1]) { 25 right -= 1; 26 } 27 // 双指针收缩 28 right--; 29 left++; 30 } 31 } 32 } 33 return arr; 34 };
18. 四数之和
先看了视频
注意以下几点:
- 一级剪枝
-
1 if (nums[k] > target && (nums[k] > 0 || target >= 0)) break; 2 //注意target 可能<0,若target<0,nums[k]>targert,而nums[k]+nums[k+1]<targer或=target 的可能是存在的! 3 //故 补充条件:要么nums[k]>0 要么target>=0
-
- 二级剪枝
- 1 if (nums[k] + nums[i] > target && (nums[k] + nums[i] >= 0)) break; 2 // 注意此时是 nums[k] + nums[i] 作为整体与target比较
代码如下:
1 /** 2 * @param {number[]} nums 3 * @param {number} target 4 * @return {number[][]} 5 */ 6 var fourSum = function(nums, target) { 7 nums.sort((a, b) => a - b) 8 let arr = new Array(); 9 for (let k = 0; k < nums.length; k++) { 10 // 一级剪枝处理 11 if (nums[k] > target && (nums[k] > 0 || target >= 0)) break; 12 // 对num[k]去重 13 if (k > 0 && nums[k] === nums[k - 1]) continue; 14 15 for (let i = k + 1; i < nums.length; i++) { 16 // 二级剪枝 17 if (nums[k] + nums[i] > target && (nums[k] + nums[i] >= 0)) break; 18 // 对num[i]去重 19 if (i > k + 1 && nums[i] === nums[i - 1]) continue; 20 21 let left = i + 1; 22 let right = nums.length - 1; 23 24 while (left < right) { 25 if (nums[i] + nums[k] + nums[left] + nums[right] > target) right--; 26 else if (nums[i] + nums[k] + nums[left] + nums[right] < target) left++; 27 else { 28 arr.push([nums[k], nums[i], nums[left], nums[right]]); 29 30 // 去重 31 while (left < right && nums[right] === nums[right - 1]) right--; 32 while (left < right && nums[left] === nums[left + 1]) left++; 33 34 // 双向收缩 35 left++; 36 right--; 37 } 38 } 39 } 40 } 41 return arr; 42 };
收获
刷题顺利,开始喜欢上刷题了!

浙公网安备 33010602011771号