《算法题讲解指南:优选算法-哈希表》--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,利用贪心思想优化查找过程。字母异位词分组,将排序后的字符串作为哈希表键值,相同键值的字符串归为一组,实现字母异位词的高效分组。**希望大家能有所收获!

相关推荐
如果'\'真能转义说5 小时前
OOXML 文档格式剖析:哈希、ZIP结构与识别
xml·算法·c#·哈希算法
夏日听雨眠5 小时前
数据结构(栈和队列)
数据结构
王老师青少年编程6 小时前
csp信奥赛C++高频考点专项训练之字符串 --【子串查找】:[NOIP 2009 提高组] 潜伏者
c++·字符串·csp·高频考点·信奥赛·子串查找·潜伏者
初願致夕霞6 小时前
基于系统调用的Linux网络编程——UDP与TCP
linux·网络·c++·tcp/ip·udp
流年如夢8 小时前
栈和列队(LeetCode)
数据结构·算法·leetcode·链表·职场和发展
小小de风呀8 小时前
de风——【从零开始学C++】(五):内存管理
开发语言·c++
CHANG_THE_WORLD9 小时前
C语言中的 %*s 和 %.*s 和C++的字符串格式化输出
c语言·c++·c#
螺丝钉的扭矩一瞬间产生高能蛋白10 小时前
QT的C++接口基础用法
c++·qt·嵌入式软件·嵌入式linux·linux应用
智者知已应修善业11 小时前
【51单片机模拟生日蜡烛】2023-10-10
c++·经验分享·笔记·算法·51单片机
智者知已应修善业11 小时前
【51单片机如何让LED灯从一亮到八,再从八亮到一】2023-10-13
c++·经验分享·笔记·算法·51单片机