leetcode题解-217. Contains Duplicate&&219.Contains Duplicate II

217,题目:Given an array of integers, find if the array contains any duplicates. Your function should return true if any value appears at least twice in the array, and it should return false if every element is distinct.
看数组中是否包含相同元素,是则返回真,否则返回假。

思路一:使用哈希表存储已经读取过的数组元素,时间复杂度为O(N),空间复杂度也是O(N)。

public boolean containsDuplicate(int[] nums) {
        Set<Integer> distinct = new HashSet<Integer>();
        for(int i=0; i<nums.length; i++)
        {
            if(distinct.contains(nums[i]))
                return true;
            distinct.add(nums[i]);
        }
        return false;
    }

思路二:先将数组排序,然后对比前后元素是否相等即可。时间复杂度为O(NlogN),空间复杂度为O(1).

public boolean containsDuplicate(int[] nums) {
        Arrays.sort(nums);
        for(int i=0; i<nums.length; i++)
        {
            if(nums[i] == nums[i+1])
                return true;
        }
        return false;
    }

思路三,将数组变为集合,比较前后的长度是否发生变化。

思路四,使用位运算来实现,使用byte数组来进行标记,这种方法目前击败了98%的方法,是很棒的实现方式!!!!

public boolean containsDuplicate(int[] nums) {
    byte[] mark = new byte[150000];
    for (int i : nums) {
        int j = i/8;
        int k = i%8;
        int check = 1<<k;
        if ((mark[j] & check) != 0) {
            return true;
        }
        mark[j]|=check;
    }
    return false;
}

219,Given an array of integers and an integer k, find out whether there are two distinct indices i and j in the array such that nums[i] = nums[j] and the difference between i and j is at most k.
相比上一题,添加了两个数的距离在k以内的要求。

思路一:使用哈希表来存储已经读取过的数组元素,记录其值和索引下标。注意,这里不要讲两个判断语句写在一起:
if (map.containsKey(nums[i])&&(i - map.get(nums[i]) <= k))
因为这样会使判断次数过多而超时。

public boolean containsNearbyDuplicate(int[] nums, int k) {
    Map<Integer, Integer> map = new HashMap<Integer, Integer>();
    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;
}

思路二:使用集合来存储K个元素,这样保留了其下标信息。使用长度为K的滑动窗口遍历数组,只要看滑动窗口内是否出现重复值即可。空间复杂度变小,且程序耗时变短。比使用HashMap更有效。

public boolean containsNearbyDuplicate(int[] nums, int k) {
        Set<Integer> set = new HashSet<Integer>();
        for(int i = 0; i < nums.length; i++){
            if(i > k) set.remove(nums[i-k-1]);
            //若集合中已经有了nums[i],则返回真。否则添加。
            if(!set.add(nums[i])) return true;
        }
        return false;
 }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值