454.四数相加II
解题思路
分别先求两个数组的和,然后剩下的两个数组的和。 最后加起来就是四个数组的和;
可以看成两个数组的和
代码
var fourSumCount = function(nums1, nums2, nums3, nums4) {
var map = new Map(),
count = 0;
for(let i = 0; i < nums1.length; i++){
for(let j = 0; j < nums2.length; j++){
let val = nums1[i] + nums2[j]
if(!map.has(val)){
map.set(val, 1)
}else{
var value = map.get(nums1[i] + nums2[j])
map.set(nums1[i] + nums2[j], value + 1)
}
}
}
for(let l = 0; l < nums3.length; l++){
for(let r = 0; r < nums4.length; r++){
let target = 0 - (nums3[l] + nums4[r]);
if(map.has(target)){
count += map.get(target);
}
}
}
return count;
};
383. 赎金信
解题思路
代码
var canConstruct = function(ransomNote, magazine) {
var map = new Map();
for(let i = 0; i< magazine.length; i++){
if(!map.has(magazine[i])){
map.set(magazine[i],1)
}else{
let val = map.get(magazine[i]);
map.set(magazine[i], val + 1);
}
}
for(let j = 0; j <ransomNote.length; j++){
let res = map.get(ransomNote[j]);
if(res > 0){
map.set(ransomNote[j], res - 1);
}else{
return false;
}
}
return true;
};
15. 三数之和
解题思路
双指针
-
先排序,后查找
-
重点:nums[i] === nums[i-1]; 去重并避免把重复结果的结果集漏掉
代码
var threeSum = function(nums) {
var res = [];
nums.sort(function(a,b){
return a-b;
});
for(let i = 0;i<nums.length; i++){
if(nums[i] > 0 ) return res;
if(i > 0 && nums[i] === nums[i - 1]) continue;
let left= i + 1, right = nums.length - 1;
while(right > left){
if((nums[i] + nums[left] + nums[right]) > 0){
right--;
}else if ((nums[i] + nums[left] + nums[right]) < 0){
left++;
}else{
res.push([nums[i], nums[left], nums[right]]);
// // right 去重
// while(left < right && (nums[right] === nums[right - 1])){
// right--;
// }
// //left 去重
// while(left < right && (nums[left] === nums[left + 1])){
// left++;
// }
// left++;
// right--;
while(left < right){
if(nums[right] === nums[right - 1]){
right--;
}else if(nums[left] === nums[left + 1]){
left++;
}else{
break;
}
}
// 如果没有找到重复的则直接相加
left++;
right--;
}
}
}
return res;
};
18. 四数之和
解题思路
在三数之和的基础上,多加一层循环
剪枝:主要是 target 有可能是负值,-6 = -5 + -1,所以需要过滤 target 负数 去重: i> 0 && nums[i] === nums[i - 1] 注意这样写
代码
var fourSum = function(nums, target) {
// target 有可能是负数
var result = [];
const len = nums.length;
if(len < 4) return result;
nums.sort(function(a, b){
return a - b;
})
for(let i = 0; i < len; i++){
//剪枝 target 负数的话, -6 = -5 + -1,所以需要过滤 target 负数
if(nums[i] > target && target > 0){
return result;
}
// 去重
if(i> 0 && nums[i] === nums[i - 1]){
continue;
}
for(let j = i + 1; j < len; j++){
let res = nums[i] + nums[j];
//剪枝 target 负数的话, -6 = -5 + -1,所以需要过滤 target 负数
//并且需要保证 j 紧跟着 i
// eg: 比如这个例子,排序后是 [-10, -9, -8, -8, -8, -7, -2, 0, 0, 1, 3, 5, 6, 7, 7, 8, 8] 在i = -2,j = 7的时候直接return了,就漏掉了0,0,1,3
if(res > target && target > 0 && i+1 == j){
return result;
}
//去重
if(j > i + 1 && nums[j] === nums[j-1]){
continue;
}
let l = j + 1, r = len - 1;
while(r > l){
let sum = nums[i] + nums[j] + nums[l] + nums[r];
if(sum > target){
r--;
}else if(sum < target){
l++;
}else{
result.push([nums[i],nums[j],nums[l],nums[r]]);
while(r > l && nums[l] === nums[l + 1]){
l++;
}
while(r > l && nums[r] === nums[r - 1]){
r--;
}
l++;
r--;
}
}
}
}
return result;
};