454.四数相加II
思路: a,b,c,d 四个数组,
1,循环把a,b 两个数组的值相加并存入map中,key为和, value为 出现的次数
2,循环c,d 2个数组,将结果 和map 中对比0-sum
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @param {number[]} nums3
* @param {number[]} nums4
* @return {number}
*/
var fourSumCount = function (nums1, nums2, nums3, nums4) {
const map = new Map()
for (n1 of nums1) {
for (n2 of nums2) {
let sum = n1 + n2
map.set(sum, (map.get(sum) || 0) + 1)
}
}
let count = 0
for (s3 of nums3) {
for (s4 of nums4) {
let sum = s3 + s4
count += map.get(0 - sum) || 0
}
}
return count
};
383. 赎金信
思路:
巧妙利用map的减法操作,避免了两次对字符串进行hash求值,再比较的复杂计算
/**
* @param {string} ransomNote
* @param {string} magazine
* @return {boolean}
*/
var canConstruct = function (ransomNote, magazine) {
let map = {}
for (let ch of magazine) {
map[ch] = map[ch] ? map[ch] + 1 : 1
}
for (let ch of ransomNote) {
if (map[ch] === undefined) return false
map[ch] -= 1
if (map[ch] < 0) return false
}
return true
};
15. 三数之和
思考: 双指针解法
/**
* @param {number[]} nums
* @return {number[][]}
*/
// 思路: 双指针方法实现
var threeSum = function (nums) {
// 排序
nums.sort((a, b) => a - b);
console.log(nums);
let ans = [];
// 循环遍历
for (let i = 0; i < nums.length; i++) {
let startNum = nums[i];
let l = i + 1;
let r = nums.length - 1;
// 最小值大于0 边界 ans是全局变量, 不可以返回 return []
if (startNum > 0) return ans;
// 去重
if (startNum === nums[i - 1]) continue;
// 双指针解法
while (l < r) {
let lNum = nums[l];
let rNum = nums[r];
let total = startNum + lNum + rNum;
if (total < 0) {
l++;
} else if (total > 0) {
r--;
} else {
ans.push([startNum, lNum, rNum]);
// 以下几行很难想的到
while (l < r && nums[l] == nums[l + 1]) {
l++;
}
while (l < r && nums[r] == nums[r - 1]) {
r--;
}
l++;
r--;
}
}
}
return ans;
};
console.log(threeSum([-1, 0, 1, 2, -1, -4]));
18. 四数之和
思考: 双指针解法, 比三数之和多一层for循环,也有点小变化
/**
* @param {number[]} nums
* @param {number} target
* @return {number[][]}
*/
var fourSum = function (nums, target) {
const len = nums.length;
if (len < 4) return [];
nums.sort((a, b) => a - b);
const res = [];
// 起止点最大为len-3
for (let i = 0; i < len - 3; i++) {
// 去重i
if (i > 0 && nums[i] === nums[i - 1]) continue;
// 起始点最大为len-2
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;
};
// 三数之和 四数之和 和hash已经没有关系了, 是双指针解法