Leetcode 219 Contains Duplicate II

本文探讨了两种高效算法,用于检测数组中是否存在相距不超过k个位置的重复元素。第一种方法使用set数据结构,确保其大小不超过k,通过检查新元素是否已存在于set中来判断重复。第二种方法利用map,存储每个元素的最新位置,通过比较新旧位置的距离来判断重复。文章详细解析了两种算法的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在这里插入图片描述
思路一: set。始终保持set的size小于等于k。遍历数组,如果数组中有这个数字,返回true;如果没有则加入set,然后这时要check set的size是否小于等于k,大于k的话则要删除最早加入set的数字。这边我们需要明白的一点是set中的数字都是数组中连续的数字,最多只保存k个数字,所以当新来一个数字的时候,此时set中的数字就是这个新来的数字的前k(也可能比k少)个数字,那么如果set中有和新来的数字相同的数字,则我们找到重复。下面展示代码:

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

思路二: map。遍历数组,key是nums[i],value是i。这边很巧妙的用到map的put方法。如果key存在的话,说明我们找到了重复,此时就要check两者下标距离是否小于等于k。怎么check呢?则是利用put的返回值,若key相同的话,新的value就代替老的value,并且回返回老的value,这个老的value其实就是那个相同的老数字的下标,那么此时我们就有了两个数的下标,简单check一下就好。这边要注意的是如果找到了重复,但是check之后并不满足小于等于k的条件,那么此时我们已经put进新数字了,原来的老数字就不见了(存在map中的是新数字的信息),那这边会不会引起麻烦呢,玩意之后的数字有和删掉的这个老数字匹配上的呢?其实这边不用担心这个问题,删掉就删掉了,因为这个数字已经没用了。为什么呢?因为之后来的数字只可能下标越来越大,你前面的都不行了,还指望后面的数字满足条件?下面展示这个思路的两种实现,其实是一样的:

class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        Map<Integer,Integer> map = new HashMap<>();
        for(int i = 0; i < nums.length; i++){
            if(map.containsKey(nums[i])){
                if(i - map.get(nums[i]) <= k)
                    return true;
            } 
            map.put(nums[i],i);
        }
        return false;
    }
}
public boolean containsNearbyDuplicate(int[] nums, int k) {
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
	
	for(int i = 0; i <  nums.length; i++) {
		Integer old = map.put(nums[i], i);
		if(ord != null && i - old <= k) {
			return true;
		}
	}
	
	return false;
}

总结:

  1. hashmap和hashtable的区别:hashmap是hashtable的轻量级实现,所以是线程不安全的,但是效率更高。hashtable是线程安全的。
  2. map.put() This method returns returns previous value associated with the key if present, else return -1.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值