力扣219(java&python)-存在重复元素 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
 

提示:

1 <= nums.length <= 105
-109 <= nums[i] <= 109
0 <= k <= 105

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/contains-duplicate-ii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

解题思路:

一、哈希表--模拟暴力求解

今天完全没看题解,解出来一道简单题,虽然很垃圾,但是还是开心的~

1.创建一个哈希表,用于将遍历的数字以 (nums[i], i) 键值对的形式存储;

2.然后遍历数组各元素,如果哈希表中不存在当前 nums[i] 则存入它的值和下标到哈希表中,如果已经存在当前 nums[i] :

  • 从哈希表中获取已存在数字的下标 j ,计算出下标之间的差值 count =  j - i(这里我感觉不用计算绝对值,因为后面的下标值肯定比已存在哈希表中的下标值大);
  • 判断count是否小于等于k,如是,则返回true,如不是,则将之前已经存在的元素删去,再存入当前值 nums[i] 和下标 i;

3.如果遍历完都不存在满足count <= k,则返回false。

java代码:

 1 class Solution {
 2     public boolean containsNearbyDuplicate(int[] nums, int k) {
 3         Map<Integer, Integer> map = new HashMap<>();
 4         for(int i = 0; i < nums.length; i++){
 5             if(map.containsKey(nums[i])){
 6                 int j = map.get(nums[i]);
 7                 int count = i - j;
 8                 if(count <= k){
 9                     return true;
10                 }else{
11                     map.remove(nums[j]);
12                     map.put(nums[i], i);
13                 }
14             }else{
15                 map.put(nums[i], i);
16             }
17         }
18         return false;
19     }
20 }

 二、滑动窗口

相当于一直维护一个大小为K的滑动窗口一直往前走,判断窗口内是否有重复元素。从前往后遍历数组元素,来记录创建一个HashSet,利用它来记录当前滑窗中出现的元素。假设当前遍历的元素为 nums[i]:

  • 如果当前set中的元素长度小于k:直接往滑窗加数,将当前元素加入 Set 中,遇到重复元素,则说明在k距离内存在重复元素,返回true;
  • 如果当前set中的元素长度大于k:将上一滑窗的最左端的元素 nums[i - k ] 移除。

如果遍历完数组中的元素没找到k距离内存在重复元素,则返回false。

关键图解:来自@画手大鹏

当遍历到i=2时nums[i] = 3,Set中不包含3,将3加入Set,Set的长度大于k,则移除窗口最左端的元素1;

当遍历到i=3时nums[i] = 1,之前的1已经被移除了,Set中不包含1,将1加入Set,Set的长度大于k,则移除窗口最左端的元素2;

当遍历到i=4时nums[i] = 3,3存在Set中,说明在k距离内存在重复元素,返回true;

java代码:

 1 class Solution {
 2     public boolean containsNearbyDuplicate(int[] nums, int k) {
 3        Set<Integer> set = new HashSet<>();
 4         for(int i = 0; i < nums.length; i++){
 5             if(set.contains(nums[i])){
 6                return true;
 7             }
 8             set.add(nums[i]); 
 9             if(set.size() > k){
10                 set.remove(nums[i - k]);
11             }
12         }
13         return false;
14     }
15 }

 python3代码:

 1 class Solution:
 2     def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
 3         s = set()
 4         n = len(nums)
 5         for i in range(n):
 6             if nums[i] in s:
 7                 return True
 8             s.add(nums[i])
 9             if len(s) > k:
10                 s.remove(nums[i - k])
11         return False

注意:

创建集合可以用{}或set()创建集合,但是创建空集合必须用set(),因为{}创建的是空字典。

posted on 2022-10-09 10:29  我不想一直当菜鸟  阅读(66)  评论(0编辑  收藏  举报