一、四数相加2
问题要点
把数组a和b的所有求和情况存入哈希表中,然后从c和d的所有求和情况中寻找是否有0 -(a+b),并累计总数
/**
* @param {number[]} nums1
* @param {number[]} nums2
* @param {number[]} nums3
* @param {number[]} nums4
* @return {number}
*/
var fourSumCount = function(nums1, nums2, nums3, nums4) {
let map = new Map
let count = 0
for(let i of nums1) {
for(let j of nums2) {
let r = i + j
map.set(r, (map.get(r) || 0) + 1)
}
}
for(let i of nums3) {
for(let j of nums4) {
let r = i + j
if(map.has(0 - r)) {
count += map.get(0 - r)
}
}
}
return count
};
二、赎金信
问题要点
哈希法:用数组作为magazine字母的出现次数,然后减去ransomNote的字母,如果能完全通过,则证明可以覆盖
/**
* @param {string} ransomNote
* @param {string} magazine
* @return {boolean}
*/
var canConstruct = function(ransomNote, magazine) {
let arr = new Array(26).fill(0)
if(ransomNote.length > magazine.length) {
return false
}
let base = 'a'.charCodeAt()
for(let i of magazine) {
arr[i.charCodeAt() - base]++
}
for(let i of ransomNote) {
if(!arr[i.charCodeAt() - base]) {
return false
}
arr[i.charCodeAt() - base]--
}
return true
};
三、三数之和
问题要点
先把数组排序,然后用双指针
/**
* @param {number[]} nums
* @return {number[][]}
*/
var threeSum = function (nums) {
nums = nums.sort((x, y) => x - y)
let res = []
for (let i = 0; i < nums.length; i++) {
if(nums[i] > 0) {
return res
}
if (nums[i] === nums[i - 1]) {
continue
}
let left = i + 1
let 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 {
res.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 res
};
四、四数之和
问题要点
和三数之和的思路一致,不同点在于这个需要双重循环,然后再用双指针,然后target也变为了任意值况
/**
* @param {number[]} nums
* @param {number} target
* @return {number[][]}
*/
var fourSum = function (nums, target) {
nums.sort((x, y) => x - y)
let res = []
let len = nums.length
for (let i = 0; i < len - 3; i++) {
if (i > 0 && nums[i] === nums[i - 1]) {
continue
}
for (let j = i + 1; j < len - 2; j++) {
if (j > i + 1 && nums[j] === nums[j - 1]) {
continue
}
let sum1 = nums[i] + nums[j]
if (sum1 > target && sum1 >= 0) {
break
}
let left = j + 1
let right = len - 1
while (left < right) {
let sum2 = sum1 + nums[left] + nums[right]
if (sum2 > target) {
right--
} else if (sum2 < target) {
left++
} else {
res.push([nums[i], nums[j], 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 res
};