前端算法系列-哈希表02

73 阅读1分钟

第454题.四数相加II

思路就是从n4优化到n2,把四个数两两分成一组,用map记录前两个数组相加得到的和以及出现的次数,后两个数组相加时去map里找,能找到就累加到count上

var fourSumCount = function(nums1, nums2, nums3, nums4) {
    let map = {}
    let count = 0
    for(let i=0;i<nums1.length;i++){
        for(let j=0;j<nums1.length;j++){
            let num = nums1[i] + nums2[j]
            if(map[num]){
                map[num] += 1
            }else{
                map[num] = 1
            }
        }
    }
    for(let i=0;i<nums1.length;i++){
        for(let j=0;j<nums1.length;j++){
            let num = 0 - ( nums3[i] + nums4[j] )
            if(map[num]){
                count += map[num]
            }
        }
    }
    return count
};

很简单,依然是常规的哈希表,记住想要把查找的复杂度从n降低到1要使用哈希表就可以了

var canConstruct = function(ransomNote, magazine) {
    let map = {}
    let flag = true 
    for(let i=0;i<magazine.length;i++){
        let word = magazine[i]
        if(map[word]){
            map[word]++
        }else{
            map[word] = 1
        }
    }
    for(let i=0;i<ransomNote.length;i++){
        let word = ransomNote[i]
        if(map[word] && map[word] > 0){
            map[word]--
        }else{
            flag = false
            break
        }

    }
    return flag
};

第15题. 三数之和

这题做了很多次了,但还是没有一次能比较完美的写出来 总体思路就是用双指针,用哈希硬做的话很难去重

var threeSum = function (nums) {
    let ans = []
    //预排序
    nums = nums.sort((a, b) => a - b)
    for (let i = 0; i < nums.length; i++) {
        if (i !== 0) {
            if (
                [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) {
                ans.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--;
            } else if (sum < 0) {
                left++; // 和小于0,就是左边值太小了,往右移
            } else if (sum > 0) {
                right--; // 和大于0,就是右边值太大了,往左移
            }
        }
    }
    return ans
}