454、四数相加 II
这个第一次看思路比较混乱,用暴力感觉不够优,暴力的时间复杂度是O(n4)
看了卡哥的思路:
其实和两数之和原理有点类似,只不过改成了先遍历前俩个数组得出和,存入map,在遍历后两个数组,然后找到map中的key,找到之后+对应的count;
根据卡哥思路实现的代码:
var fourSumCount = function (nums1, nums2, nums3, nums4) {
let sumMap = new Map();
let count = 0;
for (let i = 0; i < nums1.length; i = i + 1) {
for (let j = 0; j < nums2.length; j = j + 1) {
let sum = 0;
sum = nums1[i] + nums2[j];
sumMap.set(sum, (sumMap.get(sum) || 0) + 1);
}
}
for (let m = 0; m < nums3.length; m = m + 1) {
for (let n = 0; n < nums4.length; n = n + 1) {
let sum2 = 0;
sum2 = nums3[m] + nums4[n];
if (sumMap.get(0 - sum2)) {
count = count + sumMap.get(0 - sum2);
}
}
}
return count;
};
383. 赎金信
这个和有效异位词很像,magazine中字母出现次数存在数组中,遍力 ransom note里的字母每次1果这个值小于0,那么说明不能构成返回false.
题目链接: . - 力扣(LeetCode)
实现代码:
var canConstruct = function(ransomNote, magazine) {
const resultArray = new Array(26).fill(0);
let base = "a".charCodeAt();
for (let i = 0; i < magazine.length; i = i + 1) {
resultArray[magazine[i].charCodeAt() - base]++
}
for(let j = 0; j < ransomNote.length; j++) {
resultArray[ransomNote[j].charCodeAt() - base]--
if(resultArray[ransomNote[j].charCodeAt() - base] < 0) {
return false
}
}
return true
};
15.三数之和
题目链接:.. - 力扣(LeetCode)
感觉可以试一试双指针法,思路还是要理清一下;
卡哥思路:
用双指针法:先将数组排序,然后定义左指针(I+1)和右指针(nums.length -1) , 如果 num[I]和 num[left] 和 num[right]之和为 0, 那则找到了对应的三个数;
这里要进行一个去重操作;因为原数组里的值可能会有重复的,那么要进行判断 num[i] = num[i-1]的时候应该continue,因为i在前一个相等数的时候,已经把和为0的三个数给找到了,如果继续找,这个值就重复了; 在移动 left 和 right时,也要进行去重,以免下一个值和当前值相等
var threeSum = function (nums) {
nums = nums.sort((a, b) => a - b);
let result = [];
for (let i = 0; i < nums.length; i++) {
if (nums[i] > 0) break;
if (i > 0 && nums[i] === nums[i - 1]) continue; // 去重,如果当前数和之前那个数相等,则 continue,因为之前那个数已经找过一遍三数之和是 0 的了
let left = i + 1, right = nums.length - 1;
while (left < right) {
let sum = nums[i] + nums[left] + nums[right];
if (sum < 0) {
left++;
} else if (sum > 0) {
right--;
} else {
result.push([nums[i], nums[left], nums[right]]);
// 去重:下一个数和前一个数不同
while (left < right && nums[left] === nums[left + 1]) {
left++;
}
while (left < right && nums[right] === nums[right - 1]) {
right--;
}
left++;
right--;
}
}
}
return result;
};
18.四数之和
题目链接:. - 力扣(LeetCode)
和三数之和思路一致,多了一层循环
实现代码:
nums = nums.sort((a, b) => a - b ) let result = [] for(let k = 0; k < nums.length - 2; k = k + 1) { if(k > 0 && nums[k] === nums[k - 1]) continue for(let j = k + 1; j < nums.length - 3; j = j + 1) { let left = j + 1, right = nums.length - 1 while(left < right) { let forSum = nums[k] + nums[j] + nums[left] + nums[right] if(forSum < target) { left = left + 1 } else if(forSum > target) { right = right - 1 } else { result.push([nums[k], nums[j], nums[left], nums[right]]) while(left < right && nums[left] === nums[left + 1]) { left = left + 1 } while(left < right && nums[right-1] === nums[right]) { right = right - 1 } left = left + 1; right = right - 1 } } } } return result