【LeetCode每日一题】219:存在重复元素 II

135 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第13天,点击查看活动详情

LeetCode每日一题打卡专栏正式启动!不出意外将日更LeetCode的每日一题,敬请期待。

219:存在重复元素 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

提示:

题解:排序 & 哈希

个人题解:排序

简单题我重拳出击, 中等题我唯唯诺诺, 困难题我复制粘贴。

数据范围,直接O(nlogn)搞起,题目要求判断数组中是否存在两个相同的数,且其下标的差的绝对值<=k。于是用一结构体将数组中每个元素的值和下标存入,接着按照元素的值从小到大排序,如果元素相同,则按照索引从小到大排序

再遍历一遍数组,因为排序的规则如上,只需判断相邻的元素值是否相同,如果相同则比较两者原来的索引的差的绝对值是否<=k即可。

C++代码:

class Solution {
public:
    struct node{
        int num,pos;
        bool operator < (const node p) const{
            if(num!=p.num) return num<p.num;
            else return pos<p.pos;
        }
    };
    node a[100010];
    bool containsNearbyDuplicate(vector<int>& nums, int k) {
        int n=nums.size();
        for(int i=0;i<n;i++){
            a[i].num=nums[i];a[i].pos=i;
        }
        sort(a,a+n);
        bool flag=false;
        for(int i=0;i<n-1;i++){
            if(a[i].num==a[i+1].num){
                if(abs(a[i].pos-a[i+1].pos)<=k){
                    flag=true;break;
                }
            }
        }
        return flag;
    }
};

Java代码:

class Node {
    int num, pos;
​
    Node(int num, int pos) {
        this.num = num;
        this.pos = pos;
    }
}
​
class Cmp implements Comparator<Node> {
​
    @Override
    public int compare(Node o1, Node o2) {
        // TODO Auto-generated method stub
        if (o1.num != o2.num) {
            if (o1.num < o2.num)
                return 1;
            else
                return -1;
        } else {
            if (o1.pos < o2.pos)
                return 1;
            else
                return -1;
        }
    }
​
}
​
class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        int n = nums.length;
        Node[] a = new Node[n];
        for (int i = 0; i < n; i++) {
            Node now = new Node(nums[i], i);
            a[i] = now;
        }
        Arrays.sort(a, new Cmp());
        for (int i = 0; i < n - 1; i++) {
            if (a[i].num == a[i + 1].num) {
                if (Math.abs(a[i].pos - a[i + 1].pos) <= k) {
                    return true;
                }
            }
        }
        return false;
    }
}

官方题解:哈希

用哈希表存储每个元素的最大下标。从左到右遍历数组,例如遍历到元素nums[i]

  • 如果哈希表中存在当前元素,则比较最大下标与当前元素的下标i差的绝对值是否<=k,

    • 如果是,则返回true
    • 否则比较当前的下标,更新最大下标
  • 哈希表中插入当前下标

C++代码:

class Solution {
public:
    bool containsNearbyDuplicate(vector<int>& nums, int k) {
        int n=nums.size();
        map<int,int> mp;
        for(int i=0;i<n;i++){
            if(mp.count(nums[i])){
                if(abs(i-mp[nums[i]])<=k) return true;
                mp[nums[i]]=max(mp[nums[i]],i);
            }else mp[nums[i]]=i;
        }
        return false;
    }
};

Java代码:

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