题目:
给你一个整数数组 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(),因为{}创建的是空字典。
标签:set,java,nums,python,元素,II,int,Set,遍历 From: https://www.cnblogs.com/liu-myu/p/16771277.html