算法 LC 存在重复元素 II

题目描述

LC题 - 219
给你一个整数数组 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

题解

思路1: 暴力枚举

    static public func containsNearbyDuplicate1(_ nums: [Int], _ k: Int) -> Bool {
        let n = nums.count
        
        for i in 0..<(n-1) {
            var j = i+1
            while j <= (i+k) && j<n {
                if nums[j] == nums[i] {
                    return true
                }
                
                j += 1
               
            }
            
            
        }
        
        return false

    }

思路2:哈希表

使用哈希表记录每个元素的最大下标。从左到右遍历数组nums,当遍历到下标i时,进行如下操作:

  • 如果哈希表中已经存在和nums[i] 相等的元素且该元素在哈希表中记录的下标j满足i−j≤k,返回true;
  • 将nums[i] 和下标i存入哈希表,此时i是nums[i] 的最大下标。

上述两步操作的顺序不能改变,因为当遍历到下标i 时,只能在下标i之前的元素中寻找与当前元素相等的元素及该元素的最大下标。

当遍历结束时,如果没有遇到两个相等元素的下标差的绝对值不超过k,返回false。

    static public func containsNearbyDuplicate2(_ nums: [Int], _ k: Int) -> Bool {
        let n = nums.count
        var hash = [Int:Int]()
        
        for i in 0..<n {
            if hash.keys.contains(nums[i]) {
                if i-hash[nums[i]]! <= k {
                    return true
                }
            }
            hash[nums[i]] = i
        }
        
        return false

    }

思路3: 滑动窗口

考虑数组nums中的每个长度不超过k+1 的滑动窗口,同一个滑动窗口中的任意两个下标差的绝对值不超过k。

如果存在一个滑动窗口,其中有重复元素,则存在两个不同的下标i和j满足nums[i]=nums[j] 且∣i−j∣≤k。如果所有滑动窗口中都没有重复元素,则不存在符合要求的下标。因此,只要遍历每个滑动窗口,判断滑动窗口中是否有重复元素即可。

如果一个滑动窗口的结束下标是i,则该滑动窗口的开始下标是max(0,i−k)。可以使用哈希集合存储滑动窗口中的元素。从左到右遍历数组nums,当遍历到下标i时,具体操作如下:

  • 如果i>k,则下标i−k−1 处的元素被移出滑动窗口,因此将nums[i−k−1] 从哈希集合中删除;
  • 判断nums[i] 是否在哈希集合中,如果在哈希集合中则在同一个滑动窗口中有重复元素,返回true,如果不在哈希集合中则将其加入哈希集合。

当遍历结束时,如果所有滑动窗口中都没有重复元素,返回false。

    static public func containsNearbyDuplicate3(_ nums: [Int], _ k: Int) -> Bool {
        let n = nums.count
        var hash = [Int]()
        
        for i in 0..<n {
            if i > k {
                hash.remove(at: 0)
            }
            
            if hash.contains(nums[i]) {
                return true
            }
            
            hash.append(nums[i])
        }
        
        return false

    }

参考:https://leetcode-cn.com/problems/contains-duplicate-ii
https://leetcode-cn.com/problems/contains-duplicate-ii/solution/cun-zai-zhong-fu-yuan-su-ii-by-leetcode-kluvk/

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容