哈希表(存在重复元素||)(4)

https://blog.csdn.net/2601_95366422/article/details/159112601

上节课链接

一.题目

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

二.思路讲解

2.1 思路讲解

本题不仅需要判断数组中是否存在相同元素 ,还要检查这两个相同元素的索引之差 的绝对值是否小于等于 k 。如果直接使用双重循环,时间复杂度为 O(n²),不可取。我们需要一种能够同时记录元素值和其下标的方法,以便在遍历时快速找到之前出现过的相同元素的位置。

我们可以借助哈希表 来解决:哈希表的键存储元素值,值存储该元素最近一次出现的下标。但是,这里有一个细节:下标可能为 0 ,如果我们将下标直接存入哈希表,那么当我们检查某个元素是否出现过时,就需要通过哈希表的 findcount 来判断,而不能单纯用值是否为 0 来判断。为了简化判断,我们可以将下标 加 1 后存入哈希表,这样哈希表中的值如果大于 0,就表示该元素已经出现过,且实际下标为 值 - 1。这样,我们只需要通过哈希表的值是否为 0 就能判断元素是否存在,避免了使用 find 的开销。

三.代码演示

cpp 复制代码
class Solution {
public:
    bool containsNearbyDuplicate(vector<int>& nums, int k)
    {
        unordered_map<int, int>hash;//前面一个为元素的值,后面一个为元素的下标
        hash[nums[0]] = 1;
        for (int i = 1; i < nums.size(); i++)
        {
            if (hash[nums[i]] != 0)
            {
                int t = abs(hash[nums[i]] - 1 - i);
                if (t <= k)
                    return true;
                else
                    hash[nums[i]] = i + 1;//当这个元素和下一个元素相同元素不匹配,那么让下一个元素替换当前这个元素
            }
            else
                hash[nums[i]] = i + 1;
        }
        return false;
    }
};

四.代码讲解

一、初始化哈希表并存入第一个元素

为了在遍历过程中快速查找某个元素之前出现的位置,我们使用一个哈希表 unordered_map<int, int>,其中键为元素的值,值为该元素最近一次出现的下标加 1 (这样做的目的是为了用 0 表示该元素尚未出现过,避免与下标 0 混淆)。首先,将数组的第一个元素 nums[0] 存入哈希表,即 hash[nums[0]] = 1,表示该元素已出现,其实际下标为 0。

二、遍历剩余元素

从下标 i = 1 开始遍历数组到末尾,对于每个元素 nums[i],执行以下操作:

  1. 检查元素是否已出现过 :通过 hash[nums[i]] != 0 判断。如果该值不为 0,说明之前已经出现过该元素,且其最近一次出现的实际下标为 hash[nums[i]] - 1

  2. 计算索引差并判断 :用当前下标 i 减去之前的下标(即 hash[nums[i]] - 1),得到两者之差的绝对值(由于下标递增,差值为正,但代码中用 abs 更安全)。如果这个差值小于等于 k ,则说明找到了两个相同元素且索引差满足条件,直接返回 true

  3. 更新或插入

    • 如果差值大于 k ,说明当前这个元素虽然出现过,但距离太远,不符合要求。此时我们需要将哈希表中该元素对应的下标更新为当前下标加 1 (即 hash[nums[i]] = i + 1),这样后续再遇到相同元素时,比较的是更近的一次出现。

    • 如果元素之前从未出现过(hash[nums[i]] == 0),则直接将其存入哈希表,值为 i + 1

三、返回结果

如果遍历完整个数组都没有返回 true,说明不存在满足条件的两个相同元素,最后返回 false

四、关键细节
  • 下标加 1 存储 :这是为了用 0 表示"不存在",简化判断逻辑。否则,如果直接存储下标,需要额外判断哈希表中是否有该键,或者使用 find 方法。加 1 后只需检查值是否为 0 即可。

  • 更新策略:当遇到相同元素但距离不满足时,必须更新为当前下标,因为后续可能出现更近的相同元素,只有保留最近的下标才能保证找到最小的距离。

相关推荐
Run_Teenage2 小时前
Linux:认识信号,理解信号的产生和处理
linux·运维·算法
John.Lewis2 小时前
C++进阶(8)智能指针
开发语言·c++·笔记
被摘下的星星2 小时前
数据结构中逻辑结构和存储结构对应有哪些
数据结构
無限進步D2 小时前
蓝桥杯赛前刷题
c++·算法·蓝桥杯·竞赛
小贾要学习2 小时前
【Linux】应用层自定义协议与序列化
linux·服务器·c++·json
CoderCodingNo2 小时前
【GESP】C++二级真题 luogu-B4497, [GESP202603 二级] 数数
开发语言·c++·算法
磊 子2 小时前
八大排序之冒泡排序+选择排序
数据结构·算法·排序算法
_深海凉_2 小时前
LeetCode热题100-买卖股票的最佳时机
leetcode
We་ct2 小时前
LeetCode 50. Pow(x, n):从暴力法到快速幂的优化之路
开发语言·前端·javascript·算法·leetcode·typescript·