每日一题-存在重复元素II

153 阅读1分钟

219. 存在重复元素 II

难度简单

一、题目描述

给你一个整数数组 nums 和一个整数 k ,判断数组中是否存在两个 不同的索引 **i 和 **j ,满足 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

提示:

  • 1nums.length1051 \leq nums.length \leq 10^5
  • 109 nums[i]109-10^9 \leq nums[i] \leq 10^9
  • 0k1050 \leq k \leq 10^5

三、分析

依题意,给定数组nums和整数k,求是否存在nums[i]==nums[j],且abs(ij)kabs(i - j) \leq k
朴素的想法:(滑动窗口)在遍历数组时,当索引为i时,我们维持一个窗口[max(0, i-k), min(nums.length, i+k)],只需遍历该窗口内判断是否存在相同数组元素即可。该想法所需时间复杂度大致为O(nk)O(n*k),测试案例倒在最后一个。
进一步的,(滑动窗口+哈希表)我们可以采用hashset来存储窗口元素以降低时间复杂度。遍历数组,当索引 i>k 时,只需移除滑动窗口最前面的元素nums[i-k-1],并添加nums[i],若set中存在相同元素即可返回true。

复杂度分析

进一步后所需时间复杂度为O(n)O(n),但需额外的辅助空间,空间复杂度为O(k)O(k)。 ,

四、编码

public static boolean containsNearbyDuplicate(int[] nums, int k) {
    Set<Integer> set = new HashSet<>();
    for (int i = 0; i < nums.length; i++) {
        if (i > k) {
            set.remove(nums[i - k - 1]);
        }
        if (!set.add(nums[i])) {
            return true;
        }
    }
    return false;
}

题目链接