当前位置: 首页 > news >正文

LeetCode 哈希章节

简单

1. 两数之和

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

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

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

示例 1:

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

示例 2:

输入:nums = [3,2,4], target = 6
输出:[1,2]

示例 3:

输入:nums = [3,3], target = 6
输出:[0,1]

提示:

  • 2 <= nums.length <= 10^4
  • -10^9 <= nums[i] <= 10^9
  • -10^9 <= target <= 10^9
  • 只会存在一个有效答案

通过遍历vector不断查找如果找到对应的另一个数返回,未找到再插入哈希表,不断循环。

vector<int> twoSum(vector<int>& nums, int target) {
    unordered_map<int, int> hash;
    for (int i = 0; i < nums.size(); ++i) {
        auto it = hash.find(target - nums[i]);
        if (it != hash.end())
            return {i, it->second};
        
        hash[nums[i]] = i; // 插入哈希表
    }
    return {};
}

202. 快乐数

编写一个算法来判断一个数 n 是不是快乐数。

「快乐数」 定义为:

  • 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
  • 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
  • 如果这个过程 结果为 1,那么这个数就是快乐数。

如果 n快乐数 就返回 true ;不是,则返回 false

示例 1:

输入:n = 19
输出:true
解释:
12 + 92 = 82
82 + 22 = 68
62 + 82 = 100
12 + 02 + 02 = 1

示例 2:

输入:n = 2
输出:false

提示:

  • 1 <= n <= 2^31 - 1

有两种情况,是快乐数,不断计算能得到1;不是快乐数,不断计算会遇到之前出现过的数,会无限循环。与这题141. 环形链表类似,可以通过哈希表来记录出现过的次数即可。

int getHappyNum(int n) {
    int ret = 0;
    while (n) {
        int x = n % 10;
        ret += x * x;
        n /= 10;
    }
    return ret;
}
bool isHappy(int n) {
    unordered_map<int, int> hash;
    while (1) {
        n = getHappyNum(n);
        if (n == 1)
            return true;
        hash[n]++;
        if (hash[n] > 1)
            return false;
    }
    return false;
}

217. 存在重复元素

给你一个整数数组 nums 。如果任一值在数组中出现 至少两次 ,返回 true ;如果数组中每个元素互不相同,返回 false

示例 1:

**输入:**nums = [1,2,3,1]

**输出:**true

解释:

元素 1 在下标 0 和 3 出现。

示例 2:

**输入:**nums = [1,2,3,4]

**输出:**false

解释:

所有元素都不同。

示例 3:

**输入:**nums = [1,1,1,3,3,4,3,2,4,2]

**输出:**true

提示:

  • 1 <= nums.length <= 10^5
  • -10^9 <= nums[i] <= 10^9
bool containsDuplicate(vector<int>& nums) {
    unordered_set<int> hash;
    for (int i : nums) {
        if (hash.find(i) != hash.end())
            return true;
        hash.insert(i);
    }
    return false;
}

219. 存在重复元素 II

给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 ij ,满足 nums[i] == nums[j]abs(i - j) <= k 。如果存在,返回 true ;否则,返回 false

示例 1:

输入:nums = [1,2,3,1], k = 3
输出:true

示例 2:

输入:nums = [1,0,1,1], k = 1
输出:true

示例 3:

输入:nums = [1,2,3,1,2,3], k = 2
输出:false

提示:

  • 1 <= nums.length <= 10^5
  • -10^9 <= nums[i] <= 10^9
  • 0 <= k <= 10^5

借助贪心思想,哈希表存储对应最新的下标,可以使abs(i - j)最小。

bool containsNearbyDuplicate(vector<int>& nums, int k) {
    unordered_map<int, int> hash;
    for (int i = 0; i < nums.size(); ++i) {
        if (hash.count(nums[i]))
            if (i - hash[nums[i]] <= k)
                return true;
        hash[nums[i]] = i; // 贪心
    }
    return false;
}

面试题 01.02. 判定是否互为字符重排

给定两个由小写字母组成的字符串 s1s2,请编写一个程序,确定其中一个字符串的字符重新排列后,能否变成另一个字符串。

示例 1:

输入: s1 = "abc", s2 = "bca"
输出: true 

示例 2:

输入: s1 = "abc", s2 = "bad"
输出: false

说明:

  • 0 <= len(s1) <= 100
  • 0 <= len(s2) <= 100

通过哈希表统计字符出现次数是否相等,比排序时间复杂度更低。

bool CheckPermutation(string s1, string s2) {
    if (s1.size() != s2.size())
        return false;

    int hash[128] = {0};
    for (char ch : s1)
        ++hash[ch];
    for (char ch : s2) {
        --hash[ch];
        if (hash[ch] < 0)
            return false;
    }
    return true;
}

中等

49. 字母异位词分组

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

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

示例 1:

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

示例 2:

输入: strs = [""]
输出: [[""]]

示例 3:

输入: strs = ["a"]
输出: [["a"]]

提示:

  • 1 <= strs.length <= 10^4
  • 0 <= strs[i].length <= 100
  • strs[i] 仅包含小写字母

排序哈希

将每个string排序后作为key,建立哈希表。

vector<vector<string>> groupAnagrams(vector<string>& strs) {
    vector<vector<string>> ans;
    unordered_map<string, vector<string>> hash;
    for (auto s : strs) {
        string tmp = s;
        sort(tmp.begin(), tmp.end());
        hash[tmp].push_back(s);
    }
    for (auto p : hash)
        ans.push_back(p.second);
    return ans;
}

计算哈希

用类似哈希的思想建立数组array<int, 26>对26个字母进行计数,再通过array<int, 26>作为key,建立哈希表。

vector<vector<string>> groupAnagrams(vector<string>& strs) {
    vector<vector<string>> ans;
    map<array<int, 26>, vector<string>> hash;
    array<int, 26> word_hash;
    for (auto s : strs) {
        word_hash.fill(0);
        for (auto& ch : s)
            word_hash[ch - 'a']++;
        hash[word_hash].push_back(s);
    }
    for (auto p : hash)
        ans.push_back(p.second);
    return ans; 
}

128. 最长连续序列

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

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

示例 1:

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

示例 2:

输入:nums = [0,3,7,2,5,8,4,6,0,1]
输出:9

提示:

  • 0 <= nums.length <= 10^5
  • -10^9 <= nums[i] <= 10^9

通过unoredered_set(构造平均时间复杂度O(n))去重,以及unoredered_set(查找平均时间复杂度O(1))来完成对相邻值的查找比对。判断是不是连续序列起点降低循环次数,再循环查找相邻值进行计数。

int longestConsecutive(vector<int>& nums) {
    int ans = 0;
    unordered_set<int> num_set;
    for (auto num : nums)
        num_set.insert(num);
    for (auto num : num_set) {
        // 如果是连续序列的起点
        if (!num_set.count(num - 1)) {
            int cur = num;
            int count = 1;

            while (num_set.count(num + 1)) {
                num++;
                count++;
            }

            ans = max(count, ans);
        }
    }
    return ans;
}

相关文章:

  • Unity入门学习笔记(Day01)
  • JWT的学习
  • 探索大数据分析的无限可能:R语言的应用与实践
  • 远程登录客户端软件 CTerm 发布了 v4.0.0
  • PySide(PyQT)的contains() 方法
  • javascrip网页设计案例,SuperSlide+bootstrap+html经典组合
  • Docker中GPU的使用指南
  • 论文阅读笔记——Learning Fine-Grained Bimanual Manipulation with Low-Cost Hardware
  • 【C++指南】一文总结C++类和对象
  • Primer - 自适应学习,AI学习工具
  • 从 GitHub 批量下载项目各版本的方法
  • 2025 cv2.imwrite存储带有中文路径
  • 第三章 组件(12)- 自定义组件类库
  • Vue项目实战
  • 【Android】setText调用导致的悬浮窗抖动问题
  • 天翼云Gpu主机安装Dify手册
  • 强化学习: 继续看 Q-Learning + FrozenLake, 解决更大的地图 8x8, 10x10
  • 【CUDA】Reduce归约求和(下)
  • 谈谈 HTTP 中的重定向,如何处理301和302重定向?
  • 信息安全技术
  • 中哥两国元首共同见证签署《中华人民共和国政府与哥伦比亚共和国政府关于共同推进丝绸之路经济带和21世纪海上丝绸之路建设的合作规划》
  • “80后”德州市接待事务中心副主任刘巍“拟进一步使用”
  • 孙简任吉林省副省长
  • 习近平出席中国-拉美和加勒比国家共同体论坛第四届部长级会议开幕式
  • 牧原股份子公司与养殖户种猪买卖纠纷案一审胜诉
  • 教育部基础教育教指委:小学阶段禁止学生独自使用开放式内容生成功能