算法打卡第七天 哈希表2 力扣454,383,15,18

92 阅读1分钟

454. 四数相加 II

看到题目第一时间,我的第一反应,就是通过回溯来实现,结果发现耗时非常多,在看了大佬的解析后,发现这道题有点和两数之和有点相似,只不过这题是用map储存两两数组的和。

/**
 * @param {number[]} nums1
 * @param {number[]} nums2
 * @param {number[]} nums3
 * @param {number[]} nums4
 * @return {number}
 */
var fourSumCount = function(nums1, nums2, nums3, nums4) {
   // 看到题目后,感觉有些像两数之和的复杂版,第一反应可以用map来储存一些结果
    let count = 0;
    let twoSumMap = new Map();
    for (let n1 of nums1) {
        for (let n2 of nums2) {
            let sum = n1 + n2;
            // 用map储存nums1  + nums2的和
            twoSumMap.set(sum, (twoSumMap.get(sum) || 0) + 1);
        }
    }

    for (let n3 of nums3) {
        for (let n4 of nums4) {
            let sum = n3 + n4;
            // 查找map中有没相加n1n2和等于0的值
            count += twoSumMap.get(0 - sum) || 0;
        }
    }
    return count;
};

383. 赎金信

/**
 * @param {string} ransomNote
 * @param {string} magazine
 * @return {boolean}
 */
var canConstruct = function(ransomNote, magazine) { 
    let hash = new Array(26).fill(0);
    let base = 'a'.charCodeAt();
    // 用hash储存magazine中字符出现的次数
    for (let i = 0; i < magazine.length; i++) {
        hash[magazine[i].charCodeAt() - base]++
    }
    for (let i = 0; i < ransomNote.length; i++) {
        let index = ransomNote[i].charCodeAt() - base;
        // 如果hash表中不存在该字符,说明不能构成
        if (hash[index] <= 0) return false;
        hash[index]--;
    }       
    return true;
};

15. 三数之和

/**
 * @param {number[]} nums
 * @return {number[][]}
 */
function threeSum(nums) {
    if (!nums || nums.length < 3) return nums;
    let res = [];
    let sortArr = nums.sort((a,b)=> a -b);
    for (let i = 0; i < sortArr.length; i++) {
        // 防止重复选择
        if (i > 0 && sortArr[i] === sortArr[i - 1]) continue;
        let l = i + 1, r = sortArr.length - 1;
        while (l < r) {
            let sum = sortArr[i] + sortArr[l] + sortArr[r];
            if (sum === 0) {
                res.push([sortArr[i], sortArr[l], sortArr[r]]);
                 // 防止重复选择
                while (sortArr[l] === sortArr[l + 1]) l++;
                while (sortArr[r] === sortArr[r - 1]) r--;
                l++;
                r--;
            } else if (sum < 0) {
                l++;
            } else {
                r--;
            }
        }
    }
    return res;
}

18. 四数之和

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[][]}
 */
 // 总体比三数之和多一轮循环
var fourSum = function (nums, target) {
    const n = nums.length;
    nums.sort((a, b) => a - b);
    let sum = 0;
    let res = [];
    if (n < 4) {
        return [];
    }
    for (let i = 0; i < n - 3; i++) {
        if (i > 0 && nums[i] == nums[i - 1]) continue;
        for (let j = i + 1; j < n - 2; j++) {
            if (j > i + 1 && nums[j] == nums[j - 1]) continue;
            let l = j + 1, r = n - 1;
            while (l < r) {
                sum = nums[i] + nums[j] + nums[l] + nums[r];
                if (sum === target) {
                    res.push([nums[i], nums[j], nums[l], nums[r]]);
                    while (nums[l] === nums[l + 1]) l++;
                    while (nums[r] === nums[r - 1]) r--;
                    l++;
                    r--;
                } else if (sum < target) {
                    l++;
                } else {
                    r--;
                }
            }
        }
    }
    return res;
};

总结待补充