leetcode-哈希表练习

134 阅读1分钟

leetcode算法-几数之和

两数之和

题目

给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。 你可以按任意顺序返回答案。

解析

注意数组中同一个元素不能出现两次,我们可以时候Map映射让taget-nums[i]作为键,i作为值,如果Map映射中不存在该键,则保存与当前数匹配的值和当前数的下标,如果Map映射中有该键,则说明存在两个匹配的数,使得这两个数的和加起来等于target,然后返回在Map映射中匹配的另一个数的下标和当前数的下标

代码

var twoSum = function (nums, target) {
    let map = new Map()
    for (let i = 0; i < nums.length; i++) {
        if (!map.has(nums[i])) {
            map.set(target - nums[i], i)
        } else {
            return [map.get(nums[i]), i]
        }
    }
    return []
};

三数之和

题目

给你一个整数数组 nums ,判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i != j、i != k 且 j != k ,同时还满足 nums[i] + nums[j] + nums[k] == 0 。请 你返回所有和为 0 且不重复的三元组。 注意:答案中不可以包含重复的三元组。

解析

难点来自与不能有重复的三元组,因为这里没有要求返回数组下标,所以我们可以对原数组进行排序后进行查找,这样更方便去重,使用双指针的方法,给定一个i,left和right让他们和等于0,left = i+1, right=nums.length-1接下来的解析写在代码后面更方便理解

代码

var threeSum = function (nums) {
    if(nums.length<3) return []
    //如果nums的数组小于三,则不符合题意,直接返回
    nums.sort((a, b) => a - b)
    //排序
    let res = []
    
    for (let i = 0; i < nums.length - 1; i++) {
        if (i > 0 && nums[i] === nums[i - 1]) continue 
        //让nums[i]!==nums[i-1]。这样就不会出现重复的三元组
        let l = i + 1, r = nums.length - 1
        while (l < r) {
        //注意这里不能l <== r 因为要求不同的三个数
        
            let sum = nums[i] + nums[l] + nums[r]
            //判断sum 如果==0这说明出现了结果,如果大于0则说明可能是nums[right]太大了,让right--,如果sum小于0,则说明可能是nums[left]太小了,让left++
            
            if (sum === 0) {
                res.push([nums[i], nums[l], nums[r]])
                while (l < r && nums[l] === nums[l + 1]) {  // 去重
                    l++
                }
                while (l < r && nums[r] === nums[r - 1]) {  // 去重
                    r--
                }
            
                l++
                r--
                //这里l++, r--是为了让他们从下一个数开始
                
            } else if (sum < 0) {
                l++
            } else {
                r--
            }
        }
    }
    return res
};

四数之和

题目

给你一个由 n 个整数组成的数组 nums ,和一个目标值 target 。请你找出并返回满足下述全部条件且不重复的四元组 [nums[a], nums[b], nums[c], nums[d]] (若两个四元组元素一一对应,则认为两个四元组重复):0 <= a, b, c, d < n a、b、c 和 d 互不相同

解析

四数之和的思路跟三数之和差不多,不过要注意四数之和的去重细节,以及临界条件。

代码

var fourSum = function (nums, target) {
    if (nums.length < 4) return []
    nums.sort((a, b) => a - b)
    let res = []
    for (let i = 0; i < nums.length - 2; i++) {
        if (i > 0 && nums[i] === nums[i - 1]) continue
        for (let j = i + 1; j < nums.length - 1; j++) {
            if (j > i + 1 && nums[j] === nums[j - 1]) continue
            let l = j + 1, r = nums.length - 1
            while (l < r) {
                let sum = nums[i] + nums[j] + nums[l] + nums[r]
                if (sum === target) {
                    res.push([nums[i], nums[j], nums[l], nums[r]])
                    while (l < r && nums[l] === nums[l + 1]) {
                        l++
                    }
                    while (l < r && nums[r] === nums[r - 1]) {
                        r--
                    }
                    l++
                    r--
                } else if (sum < target) {
                    l++
                } else {
                    r--
                }
            }
        }
    }
    return res
}