赎金信
leetcode链接:leetcode.cn/problems/ra…
是242.有效的字母异位词的拓展题
两道题目思路的区别:
242中,两个字符串所包含的字母和出现的次数肯定是相同的,先将字符串1的字母次数映射到哈希表,再将字符串2的字母次数从哈希表中删除,如果两个是有效的字母异位词,最终的哈希表肯定全部都是0
383中,两个字符串所包含的字母和出现次数是会不相同的,如果按照242的思路,哈希表里面会存在不是0的元素,需要判这个元素是否已经在哈希表中,存在的话再删除,不存在则不做处理
var canConstruct = function(ransomNote, magazine) {
let hashMap = new Array(26).fill(0);
let offset = "a".charCodeAt(0);
for (let i = 0; i < ransomNote.length; i++) {
hashMap[ransomNote.charAt(i).charCodeAt(0) - offset]++;
}
for (let i = 0; i < magazine.length; i++) {
// 如果在哈希表中出现过才做减法,注意与242题目的区别
let target = magazine.charAt(i).charCodeAt(0) - offset;
if (hashMap[target]) {
hashMap[target]--;
}
}
for (let i = 0; i < hashMap.length; i++) {
if (hashMap[i] !== 0) {
return false;
}
}
return true;
};
四数相加II
leetcode链接:leetcode.cn/problems/4s…
看了视频讲解后才做出来(想着用map解决,但是变量太多了,map只存两个变量,不知道怎么用)
四数相加:a+b+c+d=0 -> a+b=-(c+d)
变量太多了就相加后再存起来(最小单位去处理)
四个数组A,B,C,D,A+B的和sum1存储在哈希表中,C+D的和sum2存储在哈希表中,判断sum1是否等于-sum2,实际代码可以优化,只使用一个map
还需要理解为什么是count += map[target],而不是count++
var fourSumCount = function(nums1, nums2, nums3, nums4) {
let count = 0;
let map = {};
// 处理A,B数组
for (let i = 0; i < nums1.length; i++) {
for (let j = 0; j < nums2.length; j++) {
let sum1 = nums1[i] + nums2[j];
if (map[sum1]) {
map[sum1]++;
} else {
map[sum1] = 1;
}
}
}
// 处理C,D数组
for (let i = 0; i < nums3.length; i++) {
for (let j = 0; j < nums4.length; j++) {
let target = 0 - (nums3[i] + nums4[j]);
if (map[target]) {
// 为什么不是count++?
count += map[target];
}
}
}
return count;
};
三数之和
leetcode链接:leetcode.cn/problems/3s…
不需要返回数组下标,可以排序,固定循环i,剩下的用双指针根据sum与target的大小进行左右收缩,题目难点在于去重
var threeSum = function(nums) {
// 先对数组进行排序,方便去重
nums.sort((a, b) => a - b);
let result = [];
for (let i = 0; i < nums.length - 2; i++) {
// i去重
if (i !== 0) {
if (nums[i] === nums[i - 1]) {
continue;
}
}
let left = i + 1;
let right = nums.length - 1;
while (left < right) {
// left去重
if (left > i + 1 && nums[left] === nums[left - 1]) {
left++;
continue;
}
// right去重
if (right < nums.length - 1 && nums[right] === nums[right + 1]) {
right--;
continue;
}
let sum = nums[i] + nums[left] + nums[right];
if (sum === 0) {
result.push([nums[i], nums[left], nums[right]]);
left++;
right--;
} else if (sum < 0) {
left++;
} else {
right--;
}
}
}
return result;
};
四数之和
leetcode链接:leetcode.cn/problems/4s…
在三数之和的思路上,多加一层循环处理,难点也是在去重
var fourSum = function(nums, target) {
nums.sort((a, b) => a - b);
let result = [];
for (let i = 0; i < nums.length - 3; i++) {
// i去重
if (i !== 0 && nums[i] === nums[i-1]) {
continue;
}
for (let j = i + 1; j < nums.length - 2; j++) {
// j去重
if (j > i + 1 && nums[j] === nums[j-1]) {
continue;
}
let left = j + 1;
let right = nums.length - 1;
while (left < right) {
// left去重
if (left > j + 1 && nums[left] === nums[left-1]) {
left++;
continue;
}
// right去重
if (right < nums.length - 1 && nums[right] === nums[right+1]) {
right--;
continue;
}
let sum = nums[i] + nums[j] + nums[left] + nums[right];
if (sum === target) {
result.push([nums[i], nums[j], nums[left], nums[right]]);
left++;
right--;
} else if (sum < target) {
left++;
} else {
right--;
}
}
}
}
return result;
};