前端力扣刷题 | 1:Hot100之 哈希

1. 两数之和

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

你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。

你可以按任意顺序返回答案。

示例:

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

法一:暴力解法
var twoSum = function(nums, target) {
    for(let i=0;i<nums.length;i++){
        for(let j=0;j<nums.length;j++){
            if(nums[i]+nums[j]===target&&i!==j){
                return [i,j];
            }
        }
    }
};
  • 时间复杂度O(n^2)
法二:使用map对象

第二个元素 = target - 第一个元素
然后判断计算出的第二个元素是否存在,若存在则返回

var twoSum = function(nums, target) {
    let map = new Map();
    for(let i=0;i<nums.length;i++){
        if(map.has(target-nums[i])){
            return [map.get(target-nums[i]),i]
        }else{
            map.set(nums[i],i);
        }
    }
    return [];
};
  • 时间复杂度:O(n) (n为数组长度)。
  • 空间复杂度:O(n) (哈希表占用的空间)。

49. 字母异位词分组

给你一个字符串数组,请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。

字母异位词 是由重新排列源单词的所有字母得到的一个新单词。

示例 :

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

解答:
  1. 排序标准化:将每个字符串的字母排序,作为字母异位词的“标准化形式”(键)。
  2. 分组存储:用一个哈希表(Map)将相同“标准化形式”的字符串分组:
    • 键:排序后的字符串;
    • 值:具有相同字母异位词的字符串数组。
  3. 提取结果:遍历完成后,返回哈希表中所有值(分组结果)的数组。
var groupAnagrams = function(strs) {
    let map = new Map();
    for(let i of strs){
        let s = [...i].sort().join("");
        if(map.has(s)){
            map.get(s).push(i);
        }else{
            map.set(s,[i]);
        }
    }
    return Array.from(map.values());
};

128. 最长连续序列

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

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

示例:

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

法一:
  1. 去重:使用集合 Set 去重,便于高效查询数字。
  2. 判断序列起点:通过检查 num - 1 是否存在,确定当前数字是否为一个序列的起点。
  3. 统计序列长度:从起点依次累加数字,统计序列长度。
  4. 更新最大长度:不断更新最长序列的长度。
  5. 返回结果:最终得到最长连续序列的长度。
var longestConsecutive = function(nums) {
    const set = new Set(nums);
    const numss = [...set];
    let res = 0;
    for (let i = 0; i < numss.length; i++) {
        if (!set.has(numss[i] - 1)) {
            let count = 1;
            while (set.has(++numss[i])) {
                count++;
            }
            res = Math.max(res, count);
        }
    }
    return res;
};
法二:
  1. 去重与快速查找:使用集合 Set 存储数组中的数字,方便快速查找数字是否存在。
  2. 判断序列起点:如果当前数字的前驱(x-1)不存在,说明它是一个连续序列的起点。
  3. 统计序列长度:从起点开始逐一判断后续数字是否存在,并统计序列长度。
  4. 更新最长序列长度:用 Math.max 保留最长的序列长度。
var longestConsecutive = function(nums) {
    let res = 0;
    let set = new Set(nums);
    for(let x of set){
        if(set.has(x-1)){
            continue;
        }
        let y = x+1;
        while(set.has(y)){
            y++;
        }
        res = Math.max(res,y-x);
    }
    return res;
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值