10、数组中重复元素2

厨子大约 3 分钟数据结构算法算法基地面试刷题

题目描述

数组中重复元素 2open in new window

给定一个整数数组和一个整数 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

Hashmap

这个题目和我们上面那个数组中的重复数字几乎相同,只不过是增加了一个判断相隔是否小于 K 位的条件,我们先用 HashMap 来做一哈,和刚才思路一致,我们直接看代码就能整懂

代码

Java Code:

class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        //特殊情况
        if (nums.length == 0) {
            return false;
        }
        // hashmap
        HashMap<Integer,Integer> map = new HashMap<>();
        for (int i = 0; i < nums.length; i++) {
            // 如果含有
            if (map.containsKey(nums[i])) {
                //判断是否小于K,如果小于等于则直接返回
                int abs = Math.abs(i - map.get(nums[i]));
                if (abs <= k)  return true;//小于等于则返回
            }
            //更新索引,此时有两种情况,不存在,或者存在时,将后出现的索引保存
            map.put(nums[i],i);
        }
        return false;
    }
}

Python3 Code:

from typing import List
class Solution:
    def containsNearbyDuplicate(self, nums: List[int], k: int)->bool:
        # 特殊情况
        if len(nums) == 0:
            return False
        # 字典
        m = {}
        for i in range(0, len(nums)):
            # 如果含有
            if nums[i] in m.keys():
                # 判断是否小于K,如果小于等于则直接返回
                a = abs(i - m[nums[i]])
                if a <= k:
                    return True# 小于等于则返回
            # 更新索引,此时有两种情况,不存在,或者存在时,将后出现的索引保存
            m[nums[i]] = i
        return False

C++ Code:

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

Swift Code

class Solution {
    func containsNearbyDuplicate(_ nums: [Int], _ k: Int) -> Bool {
        if nums.count == 0 {
            return false
        }
        var dict:[Int:Int] = [:]
        for i in 0..<nums.count {
            // 如果含有
            if let v = dict[nums[i]] {
                // 判断是否小于K,如果小于等于则直接返回
                let abs = abs(i - v)
                if abs <= k {
                    return true
                }
            }
            // 更新索引,此时有两种情况,不存在,或者存在时,将后出现的索引保存
            dict[nums[i]] = i
        }
        return false
    }
}

HashSet

解析

这个方法算是属于固定滑动窗口。我们需要维护一个长度为 K 的滑动窗口,如果窗口内含有该值,则直接返回 true,尾部进入新元素时,则将头部的元素去掉。继续查看是否含有该元素。下面我们来看视频解析吧,保证以下就能搞懂了。

img
img

代码

Java Code

class Solution {
    public boolean containsNearbyDuplicate(int[] nums, int k) {
        //特殊情况
        if (nums.length == 0) {
            return false;
        }
        // set
        HashSet<Integer> set = new HashSet<>();
        for (int i = 0; i < nums.length; ++i) {
            //含有该元素,返回true
            if (set.contains(nums[i])) {
                return true;
            }
            // 添加新元素
            set.add(nums[i]);
            //维护窗口长度
            if (set.size() > k) {
                set.remove(nums[i-k]);
            }
        }
        return false;
    }
}

Python3 Code:

from typing import List
class Solution:
    def containsNearbyDuplicate(self, nums: List[int], k: int)->bool:
        # 特殊情况
        if len(nums) == 0:
            return False
        # 集合
        s = set()
        for i in range(0, len(nums)):
            # 如果含有,返回True
            if nums[i] in s:
                return True
            # 添加新元素
            s.add(nums[i])
            # 维护窗口长度
            if len(s) > k:
                s.remove(nums[i - k])
        return False

C++ Code:

class Solution {
public:
    bool containsNearbyDuplicate(vector<int>& nums, int k) {
        multiset <int> S;
        for(int i = 0; i < nums.size(); ++i){
            if(S.count(nums[i])) return true;
            S.insert(nums[i]);
            if(S.size() > k) S.erase(nums[i - k]);
        }
        return false;
    }
};

Swift Code

class Solution {
    func containsNearbyDuplicate(_ nums: [Int], _ k: Int) -> Bool {
        if nums.count == 0 {
            return false
        }
        var set:Set<Int> = []
        for i in 0..<nums.count {
            // 含有该元素,返回true
            if set.contains(nums[i]) {
                return true
            }
            // 添加新元素
            set.insert(nums[i])
            if set.count > k {
                set.remove(nums[i - k])
            }
        }
        return false
    }
}

Go Code:

func containsNearbyDuplicate(nums []int, k int) bool {
    length := len(nums)
    if length == 0 {
        return false
    }
    m := map[int]int{}
    for i := 0; i < length; i++ {
        if v, ok := m[nums[i]]; ok {
            if i - v <= k {
                return true
            }
        }
        m[nums[i]] = i
    }
    return false
}