代码随想录的第六天
454. 四数相加 II
哈希表
var fourSumCount = function(nums1, nums2, nums3, nums4) {
const map = new Map()
for (let i = 0; i < nums1.length; i++) {
for (let j = 0;j < nums2.length; j++) {
const temp = nums1[i] + nums2[j]
if (map.has(temp)) {
map.set(temp, map.get(temp) + 1)
} else {
map.set(temp, 1)
}
}
}
let count = 0
for (let m = 0; m < nums3.length; m++) {
for (let n = 0; n < nums4.length; n++) {
const temp2 = nums3[m] + nums4[n]
if (map.has(-temp2)) {
count = count + map.get(-temp2)
}
}
}
return count
};
思路:
1、首先暴力解法不行,四个循环嵌套会直接崩
2、减少到两个循环,先将前面两个数组的数字所有情况进行相加存储,然后存储次数
3、再用相同办法整合后面两个数组,当两个集合的数字相加为0即是一个元组,将存储的次数相加即可
383. 赎金信
var canConstruct = function(ransomNote, magazine) {
const map = new Map()
for (let i = 0; i < ransomNote.length; i++) {
if (map.has(ransomNote[i])) {
map.set(ransomNote[i], map.get(ransomNote[i]) + 1)
} else {
map.set(ransomNote[i], 1)
}
}
for (let j = 0;j < magazine.length; j++) {
if (map.has(magazine[j])) {
map.set(magazine[j], map.get(magazine[j]) - 1)
if (map.get(magazine[j]) === 0) {
map.delete(magazine[j])
}
}
}
return map.size ? false : true
};
思路:
这个就是套壳版的有效的字母异位词,思路就不多阐述了
15. 三数之和
var threeSum = function(nums) {
let arr = []
nums = nums.sort((a,b) => a - b)
for (let i = 0; i < nums.length; i++) {
if (nums[i] > 0) return arr
if (i > 0 && nums[i] === nums[i - 1]) continue
let left = i + 1
let right = nums.length - 1
while (right > left) {
if (nums[i] + nums[left] + nums[right] === 0) {
arr.push([nums[i], nums[left], nums[right]])
while (right > left && nums[right] === nums[right - 1]) right--
while (right > left && nums[left] === nums[left + 1]) left++
left++
right--
} else if (nums[i] + nums[left] + nums[right] > 0) {
right--
} else if (nums[i] + nums[left] + nums[right] < 0) {
left++
}
}
}
return arr
};
思路:
1、双指针+循环的解法
2、首先将数组进行排序?因为要顺序去指针遍历
3、遍历排序后的数组,当nums[i]大于0的时候,说明后面都是正数了,所以不会为0,直接返回数组就行
4、当nums[i]和上一个相等的时候,相当于我已经收集了一个相同的所以,直接跳过不进行收集,为什么要和上一个比较?因为下一个就是left指针,他们是肯定不能相同的
5、然后左右指针和当前i相加,大于0右指针左移,小于0左指针右移?因为数组是顺序的
6、等于0的时候然后塞进去数组,注意:左右指针下一个有可能还是和他本身一样,所以要一直跳过,直到不一样的,然后左右向中心靠拢
18. 四数之和
var fourSum = function(nums, target) {
const arr = []
nums.sort((a,b) => a-b)
for (let i = 0; i < nums.length - 1; i++) {
if (i > 0 && nums[i] === nums[i - 1]) continue
for (let j = i + 1; j < nums.length; j++) {
if (j > i + 1 && nums[j] === nums[j - 1]) continue
let left = j + 1
let right = nums.length - 1
while (left < right) {
if (nums[i] + nums[j] + nums[left] + nums[right] > target) {
right--
} else if (nums[i] + nums[j] + nums[left] + nums[right] < target) {
left++
} else {
arr.push([nums[i], nums[j], nums[left], nums[right]])
while (nums[right] === nums[right - 1]) right--
while (nums[left] === nums[left + 1]) left++
right--
left++
}
}
}
}
return arr
};
思路:
1、三数之和的加强升级版
2、思路就是在外层再包裹一层循环,一个下标0开始,一个1开始,需要注意的是,因为第二层下标是第一层加一开始,所以第一层下标length-1即可
3、注意,target是有可能负数的,所以不能用首节点大于target去进行判断
4、剩下和三数之和基本一样,不再赘述