《算法题讲解指南:优选算法-哈希表》--58.存在重复元素I,59.存在重复元素II,60.字母异位词分组

🔥小叶-duck个人主页

❄️个人专栏《Data-Structure-Learning》《C++入门到进阶&自我学习过程记录》
《算法题讲解指南》--优选算法
《算法题讲解指南》--递归、搜索与回溯算法
《算法题讲解指南》--动态规划算法

未择之路,不须回头
已择之路,纵是荆棘遍野,亦作花海遨游


目录

58.存在重复元素I

题目链接:

题目描述:

题目示例:

解法(哈希表):

算法思路:

C++算法代码:

59.存在重复元素II

题目链接:

题目描述:

题目示例:

解法(哈希表):

算法思路:

C++算法代码:

60.字母异位词分组

题目链接:

题目描述:

题目示例:

解法(哈希表+排序):

算法思路:

C++算法代码:

算法总结及流程解析:

结束语


58.存在重复元素I

题目链接:

217. 存在重复元素 - 力扣(LeetCode)

题目描述:

题目示例:

解法(哈希表):

算法思路:

分析一下题目,出现「至少两次」的意思就是数组中存在着重复的元素,因此我们可以无需统计元素出现的数目。仅需在遍历数组的过程中,检查当前元素「是否在之前已经出现过」即可。

因此我们可以利用哈希表,仅需存储数「组内的元素」。在遍历数组的时候,一边检查哈希表中是否已经出现过当前元素,一边将元素加入到哈希表中。

C++算法代码:

cpp 复制代码
class Solution {
public:
    bool containsDuplicate(vector<int>& nums) 
    {
        if(nums.size() == 1)
        {
            return false;
        }    
        unordered_map<int, int> hash;
        for(int i = 0; i < nums.size(); i++)
        {
            hash[nums[i]]++;
            if(hash[nums[i]] > 1)
            {
                return true;
            }
        }
        return false;
    }
};

59.存在重复元素II

题目链接:

219. 存在重复元素 II - 力扣(LeetCode)

题目描述:

题目示例:

解法(哈希表):

算法思路:

解决该问题需要我们快速定位到两个信息:

两个相同的元素;

这两个相同元素的下标。

因此,我们可以使用「哈希表」,令数组内的元素做key值,该元素所对应的下标做val值,将「数组元素」和「下标」绑定在一起,存入到「哈希表」中。

思考题:

如果数组内存在大量的「重复元素」,而我们判断下标所对应的元素是否符合条件的时候,需要将不同下标的元素作比较,怎么处理这个情况呢?

答:这里运用了一个「小贪心」。

我们按照下标「从小到大」的顺序遍历数组,当遇到两个元素相同,并且比较它们的下标时,这两个下标一定是距离最近的,因为:

如果当前判断符合条件直接返回true,无需继续往后查找。

如果不符合条件,那么前一个下标一定不可能与后续相同元素的下标匹配(因为下标在逐渐变大),那么我们可以大胆舍去前一个存储的下标,转而将其换成新的下标,继续匹配。

C++算法代码:

cpp 复制代码
class Solution {
public:
    bool containsNearbyDuplicate(vector<int>& nums, int k) 
    {
        //解法:哈希表
        if(k == 0)
        {
            return false;
        }
        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;
    }
};

60.字母异位词分组

题目链接:

49. 字母异位词分组 - 力扣(LeetCode)

题目描述:

题目示例:

解法(哈希表+排序):

算法思路:

互为字母异位词的单词有一个特点:将它们「排序」之后,两个单词应该是「完全相同」的。

所以,我们可以利用这个特性,将单词按照字典序排序,如果排序后的单词相同的话,就划分到同一组中。

这时我们就要处理两个问题:

排序后的单词与原单词需要能互相映射;

将排序后相同的单词,「划分到同一组」;

利用语言提供的「容器」的强大的功能就能实现这两点:

将排序后的字符串( string )当做哈希表的 key 值;

将字母异位词数组( vector<string> )当成 val 值。

定义一个「哈希表」即可解决问题。

C++算法代码:
cpp 复制代码
class Solution {
public:
    vector<vector<string>> groupAnagrams(vector<string>& strs) 
    {
        unordered_map<string, vector<string>> hash;
        //键为string,表示的是strs每个字符串通过ascll码值重排序的结果
        //如果存在则说明两者是异位词,如果不存在则相当于插入
        //值为vector<string>,表示的是对应相同的键在vector<string>存放的所有结果
        //后续只需要取出来即可

        //1、把所有的字母异位词分组
        for(auto str : strs)
        {
            string tmp = str;
            sort(tmp.begin(), tmp.end());
            hash[tmp].push_back(str);
        }
        //2、结果从哈希表提取出来
        vector<vector<string>> ret;
        for(auto [k, v] : hash)
        {
            //k对应的是键,v对应的是值,我们是需要将hash中的值也就是vector<string>放入ret中
            ret.push_back(v);
        }
        return ret;
    }
};

算法总结及流程解析:

结束语

到此,58.存在重复元素I,59.存在重复元素II,60.字母异位词分组 这三道算法题就讲解完了。**存在重复元素I,使用哈希表快速检测数组中是否存在重复元素,只需判断元素是否已存在哈希表中即可。存在重复元素II,在哈希表中同时存储元素和下标,检查相同元素的下标差是否≤k,利用贪心思想优化查找过程。字母异位词分组,将排序后的字符串作为哈希表键值,相同键值的字符串归为一组,实现字母异位词的高效分组。**希望大家能有所收获!

相关推荐
吴可可1231 小时前
CAD2004自定义实体开发环境配置
c++·算法
L_09071 小时前
【C++】C++11 新特性
开发语言·c++
AI人工智能+电脑小能手1 小时前
【大白话说Java面试题 第89题】【Mysql篇】第19题:Hash 索引和 B+ 树索引的区别?它们在使用方面的区别?
java·数据库·mysql·面试·哈希算法
Fanfanaas1 小时前
C++ 继承
java·开发语言·jvm·c++·学习·算法
十五年专注C++开发2 小时前
cereal 库:C++ 序列化的轻量之选
开发语言·c++·序列化·反序列化·cereal
lqqjuly2 小时前
设计模式:理论、架构与 C++ 实现—SOLID原则到23 种经典模式
c++·设计模式·架构
BestOrNothing_20152 小时前
C++零基础到工程实战(5.2.8)多文件声明定义函数和全局变量
c++·c++多文件编译·.h头文件·.cpp·函数声明定义
星卯教育tony2 小时前
2026年全国青少年信息素养大赛主题应用 数字守艺人 丝路新城 星火征程 智传民韵 c++ python scratch 所有真题免费分享
开发语言·c++
ID_180079054732 小时前
淘宝商品详情数据接口深度解析:架构、鉴权、数据结构与实战
数据结构·架构
basketball6162 小时前
C++ bitset 头文件完全指南
开发语言·c++