454.四数相加II
题目链接:454.四数相加II
解题思路🤔
1、首先将四个数组两两分开,求数组元素之和,和出现的次数,放到map中。
2、将求和问题转化为求差问题。 在map中寻找 0-(c+d),把map中key对应的value,即出现次数统计出来。
代码⌨️
var fourSumCount = function(nums1, nums2, nums3, nums4) {
const twoSumMap = new Map();
let count = 0;
// 统计nums1和nums2数组元素之和,和出现的次数,放到map中
for(const n1 of nums1) {
for(const n2 of nums2) {
const sum = n1 + n2;
twoSumMap.set(sum, (twoSumMap.get(sum) || 0) + 1)
}
}
// 找到如果 0-(c+d) 在map中出现过的话,就把map中key对应的value也就是出现次数统计出来
for(const n3 of nums3) {
for(const n4 of nums4) {
const sum = n3 + n4;
count += (twoSumMap.get(0 - sum) || 0)
}
}
return count;
};
总结👀
383. 赎金信
题目链接:383. 赎金信
解题思路🤔
1、数组在哈希表中的应用。
2、用一个长度为26的数组来记录magazine里字母出现的次数。
3、然后再用ransomNote去验证这个数组是否包含了ransomNote所需要的所有字母。
代码⌨️
var canConstruct = function(ransomNote, magazine) {
const strArr = new Array(26).fill(0),
base = "a".charCodeAt();
for(const s of magazine) { // 记录 magazine里各个字符出现次数
strArr[s.charCodeAt() - base]++;
}
for(const s of ransomNote) { // 对应的字符个数做--操作
const index = s.charCodeAt() - base;
if(!strArr[index]) return false; // 如果没记录过直接返回false
strArr[index]--;
}
return true;
};
总结👀
为什么没有用map?
在本题的情况下,使用map的空间消耗要比数组大一些。因为map要维护红黑树或者哈希表,且还要做哈希函数,是费时的!当数据量大时 就能体现出来差别了。所以数组更加简单直接有效!
15. 三数之和🔥🔥🔥🔥
题目链接:15. 三数之和
解题思路🤔
1、通过双指针方法,查找所有的组合
2、第一步要先将数组排序。
3、怎样进行剪枝和去重。
4、因为要求返回的是数值,满足要求的集合。所以可以用双指针法,而两数之和中要求返回索引下标,双指针法一定要排序,导致索引改变,无法使用双指针法。
代码⌨️
var threeSum = function(nums) {
const res = [], len = nums.length
// 将数组排序
nums.sort((a, b) => a - b)
for (let i = 0; i < len; i++) {
let l = i + 1, r = len - 1, iNum = nums[i]
// 数组排过序,如果第一个数大于0直接返回res
if (iNum > 0) return res
// 去重
if (iNum == nums[i - 1]) continue
while(l < r) {
let lNum = nums[l], rNum = nums[r], threeSum = iNum + lNum + rNum
// 三数之和小于0,则左指针向右移动
if (threeSum < 0) l++
else if (threeSum > 0) r--
else {
res.push([iNum, lNum, rNum])
// 去重
while(l < r && nums[l] == nums[l + 1]){
l++
}
while(l < r && nums[r] == nums[r - 1]) {
r--
}
l++
r--
}
}
}
return res
};
18. 四数之和🔥🔥🔥🔥
题目链接:18. 四数之和
解题思路🤔
1、双指针法
代码⌨️
var fourSum = function(nums, target) {
const len = nums.length;
if(len < 4) return [];
nums.sort((a, b) => a - b);
const res = [];
for(let i = 0; i < len - 3; i++) {
// 去重i
if(i > 0 && nums[i] === nums[i - 1]) continue;
for(let j = i + 1; j < len - 2; j++) {
// 去重j
if(j > i + 1 && nums[j] === nums[j - 1]) continue;
let l = j + 1, r = len - 1;
while(l < r) {
const sum = nums[i] + nums[j] + nums[l] + nums[r];
if(sum < target) { l++; continue}
if(sum > target) { r--; continue}
res.push([nums[i], nums[j], nums[l], nums[r]]);
// 对nums[left]和nums[right]去重
while(l < r && nums[l] === nums[++l]);
while(l < r && nums[r] === nums[--r]);
}
}
}
return res;
};