哈希表(存在重复元素||)(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 即可。

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

相关推荐
ward RINL13 分钟前
# GPT-5.6-sol vs GPT-5.5 新题实测:非弹性碰撞物理题和稳定路由算法
网络·gpt·算法
灯澜忆梦13 分钟前
【dp_1】爬楼梯 | 斐波那契数 | 第 N 个泰波那契数 | 三步问题
算法·golang
十五年专注C++开发22 分钟前
C++之std::numeric_limits介绍
开发语言·c++·limits
星释34 分钟前
鸿蒙智能体开发实战:35.鸿蒙壁纸大师 - 调用火山引擎模型生成壁纸
算法·华为·ai·harmonyos·鸿蒙·火山引擎
小七在进步43 分钟前
数据结构:用栈实现队列
开发语言·数据结构
geovindu1 小时前
go: Floyd-Warshall Algorithms
开发语言·后端·算法·golang
db_murphy1 小时前
机器学习决策树的基尼系数是个啥?
学习·算法
2301_800256111 小时前
数据结构基础hw9判断选择题、hw7编程题、hw12编程题
数据结构·算法
拳里剑气1 小时前
C++算法:优先级队列
开发语言·c++·算法·优先级队列