leetcode 219 存在重复元素 II

给定一个整数数组和一个整数 k,判断数组中是否存在两个不同的索引 i 和 j,使得 nums [i] = nums [j],并且 i 和 j 的差的 绝对值 至多为 k。
示例 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

O(N^2)解法 暴力破解

首先最容易想到的解法就是用O(n^2)复杂度暴力解法
两个指针,第一个指针是定在前面,第二个指针后移,
大概思路如我画的图所示
在这里插入图片描述
通过第一个指针的index和第二个指针index不断的转移,最终找到j-i<k并且两个所指的数字相等的结果返回布尔值。

    public boolean containsNearbyDuplicate(int[] nums, int k) {
        for (int i = 0; i < nums.length; i++) {
            for (int j = i + 1; j < nums.length; j++) {
                if (nums[i] == nums[j] && j - i  <= k) {
                    return true;
                }
            }
        }
        return false;
    }

O(N)解法(1)

我并不满足与On^2这个解法,因为效率很低,考虑了一下可以用Map记录这个val的位置具体示意图如下
在这里插入图片描述

实例化一个Map相当于一个字典(类型Map(Integer,Integer))用当前指针索引指向的值做key,用当前索引的位置做val,假如key在这个Map中存在,就用当前这个指针的位置与map中key记录的索引值相减,最后与k相比较,假如说大了,那就更新这个key,假如小了,那就返回布尔值结果,这样的复杂度能做到log(N)

    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])) {
                int existIdx = map.get(nums[i]);
                if (i - existIdx <= k) {
                    return true;
                }else {
                    map.put(nums[i], i);
                }
            } else {
                map.put(nums[i], i);
            }
        }
        return false;
    }

O(N)解法(2)

第二种解法使用的是Set,和前面Map记录值的不同的是,利用set可以做到类似滑动窗口一样的效果,思路是先将元素加入Set中,但是这个Set的长度不能超过k,假如超过k的话,则需要移除第一个值维护这个窗口的规定大小,然后不断的往前移,知道在i个元素与set里面某个元素相等为止。
在这里插入图片描述

    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;
    }
回顾217号 存在重复元素

给定一个整数数组,判断是否存在重复元素。
如果任意一值在数组中出现至少两次,函数返回 true 。如果数组中每个元素都不相同,则返回 false 。

如果用O(N)解法一去解,加之前先看看是否存在,这个问题是不是会少很多呢?
在用Set之前,我曾考虑过用最大空间数组,然后对num[i]标记这个思路去解,但是md居然没考虑到这个num[i]有负数存在,失败了,到后面还是用了set,添加之前先检查是否存在了这个值的这个思路,才是正解!

    public boolean containsDuplicate(int[] nums) {
        Set<Integer> res = new HashSet<>();
        for (int i = 0; i < nums.length; i++) {
            if (res.contains(nums[i])) {
                return true;
            }
            res.add(nums[i]);
        }
        return false;
    }
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值