代码随想录的第六天

71 阅读1分钟

代码随想录的第六天

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、剩下和三数之和基本一样,不再赘述