每天一算:Contains Duplicate II

Contains Duplicate II

leetcode上第219号问题:Contains Duplicate II

给出⼀个整形数组nums和⼀个整数k,是否存在索引i和j,使得nums[i] == nums[j] 且i和j之间的差不超过k

Example 1:  
Input: nums = [1,2,3,1], k = 3    
Output: true.

Example 2:    
Input: nums = [1,0,1,1], k = 1  
Output: true

Example 3:    
Input: nums = [1,2,3,1,2,3], k = 2  
Output: false

思路

考虑用滑动窗口与查找表来解决。

  • 设置查找表record,用来保存每次遍历时插入的元素,record的最大长度为k

  • 遍历数组nums,每次遍历的时候在record查找是否存在相同的元素,如果存在则返回true,遍历结束

  • 如果此次遍历在record未查找到,则将该元素插入到record中,而后查看record的长度是否为k + 1

  • 如果此时record的长度是否为k + 1,则删减record的元素,该元素的值为nums[i - k]

  • 如果遍历完整个数组nums未查找到则返回false

动画演示

每天一算:Contains Duplicate II
动画演示

代码

 1// 219. Contains Duplicate II
2// https://leetcode.com/problems/contains-duplicate-ii/description/
3// 时间复杂度: O(n)
4// 空间复杂度: O(k)
5class Solution {
6public:
7    bool containsNearbyDuplicate(vector<int>& nums, int k) {
8
9        if(nums.size() <= 1)  return false;
10
11        if(k <= 0)  return false;
12
13
14        unordered_set<int> record;
15        for(int i = 0 ; i < nums.size() ; i ++){
16
17            if(record.find(nums[i]) != record.end()){
18                return true;
19            }
20
21            record.insert(nums[i]);
22
23            // 保持record中最多有k个元素
24            // 因为在下一次循环中会添加一个新元素,使得总共考虑k+1个元素
25            if(record.size() == k + 1){
26                record.erase(nums[i - k]);
27            }
28        }
29
30        return false;
31    }
32};

执行结果

每天一算:Contains Duplicate II
执行结果