[JavaScript刷题] LeetCode Hot 100 - Hash

237 阅读3分钟

两数之和

题目: 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target  的那 两个 整数,并返回它们的数组下标。

  • 假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
  • 可以按任意顺序返回答案

示例:

输入: nums = [2,7,11,15], target = 9
输出: [0,1]
解释: 因为 nums[0] + nums[1] == 9 ,返回 [0, 1]

解题:
要找出两数之和为target的两个整数的下标,基本思路是遍历传入的数组,并寻找 target - curr对应的值是否存在,存在则返回,不存在则将当前值存入一个Hash表中,等待下次遍历。

/**
 * @param {number[]} nums
 * @param {number} target
 * @return {number[]}
 */
var twoSum = function(nums, target) {
    if(!nums.length) return [];
    const map = new Map();
    const len = nums.length;
    for(let i = 0; i < len; i++) {
        if(i === 0) {
           15806923589
        }
        const curr = target - nums[i];
        if(map.has(curr)) {
            return [i, map.get(curr)]
        }
        map.set(nums[i], i);
    }
};

字母异位词分组

题目: 给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

示例:

输入: strs = ["eat", "tea", "tan", "ate", "nat", "bat"]
输出: [["bat"],["nat","tan"],["ate","eat","tea"]]

解题:
字母的异位词就是由若干个相同字母组成的单词,比如上面的eat, tea,都是由e, a, t单个字母组成,就属于异位词。
本题的思路是创建一个Map集合,遍历传入的数组,将每个单词的字母顺序重新排序后作为key值,单词本身存入一个数组中作为value值,遍历完成后返回该集合的value值即可。

/**
 * @param {string[]} strs
 * @return {string[][]}
 */
var groupAnagrams = function(strs) {
    const len = strs.length;
    if(len === 0) return [];
    if(len === 1) return [strs];
    const map = new Map();

    for(let i = 0; i < len; i++) {
        const curr = strs[i];
        const key = curr.split("").sort().join("");

        if(map.has(key)) {
            map.get(key).push(curr);
        } else {
            map.set(key, [curr])
        }
    }
    return [...map.values()];
};

最长连续序列

题目: 给定一个未排序的整数数组 nums ,找出数字连续的最长序列(不要求序列元素在原数组中连续)的长度。

  • 请你设计并实现时间复杂度为 O(n) 的算法解决此问题。

示例:

输入:nums = [100,4,200,1,3,2]
输出:4
解释:最长数字连续序列是 [1, 2, 3, 4]。它的长度为 4

解题:
这一题要求算法的时间复杂度要满足O(n),思路是先将传入的数组变成一个集合,遍历该集合并判断当前元素是否是最开始的元素,若是,则从该元素开始找到与之对应的连续序列,并将其长度与当前最长的连续序列的长度进行比较,若比它长,则替换。

/**
 * @param {number[]} nums
 * @return {number}
 */
var longestConsecutive = function(nums) {
   // 生成一个集合
   const numSet = new Set(nums);
   // 记录最大序列的长度
   let longestStreak = 0;

   for (let num of numSet) {
     // 判断是否是一个序列的开始元素
     if (!numSet.has(num - 1)) {
       let currentStreak = 1;
       // 开始计算该序列的最大长度
       while (numSet.has(++num)) {
         currentStreak++;
       }
       // 与当前最大序列的长度进行比较取最大值
       longestStreak = Math.max(longestStreak, currentStreak);
     }
   }
   return longestStreak;
};