题目
给定一个整数数组 nums 和一个整数 k,判断是否存在两个不同的索引 i, j,使得 nums[i] = nums[j],且 i, j 之差最多为 k。
难度:容易
编程语言:C++
分析
程序框架为:
1 2 3 4 5 6
| class Solution { public: bool containsNearbyDuplicate(vector<int>& nums, int k) { } };
|
我的思路是:
- 取 i = 0,j = k,判断是否 nums[i] = nums[j],是则 return true,否则 i, j 分别 +1,重复本步骤直到 j = nums.size()-1。
- 来到第 2 步,说明没有找到两个不同的索引 i, j,使得 nums[i] = nums[j],且 i, j 之差为 k,所以 k -= 1,继续第 1 步,直到 k = 1。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include <frequently-used-code-snippets.h> class Solution { public: bool containsNearbyDuplicate(vector<int>& nums, int k) { for (; k > 0; k--) { for (int i = 0, j = k; j < nums.size(); i++, j++) { if (nums[i] == nums[j]) { return true; } } } return false; } }; int main() { int array[] = { 1, 2, 3, 4, 2, 1 }; vector<int> nums = convertArrayToVector(array, ARRAY_LENGTH(array)); Solution sol; cout << sol.containsNearbyDuplicate(nums, 2); }
|
提交到 Leetcode,Time Limit Exceeded! 导致超时的输入为 nums = { 0, 1, 2, 3, …, 29999 },k = 15000。上面代码的时间复杂度为 O(n^2)。
那就换个思路,每遍历 nums 一个元素,放到 map<int, int>
里,key 为元素值,value 为元素索引。如果当前元素不存在于 map,那么 添加到 map。如果已存在于 map,判断两个索引之差是否 <= k,如果是 retur true,否则更新 value 值。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47
| #include <frequently-used-code-snippets.h> class Solution { public: bool containsNearbyDuplicate(vector<int>& nums, int k) { for (; k > 0; k--) { for (int i = 0, j = k; j < nums.size(); i++, j++) { if (nums[i] == nums[j]) { return true; } } } return false; } bool containsNearbyDuplicate2(vector<int>& nums, int k) { map<int, int> m; for (int i = 0; i < nums.size(); i++) { int key = nums[i]; int val = i; map<int, int>::iterator iter = m.find(key); if (iter != m.end()) { if (val - iter->second <= k) { return true; } else { iter->second = val; } } else { m[key] = val; } } return false; } }; int main() { int array[] = { 1, 2, 1 }; vector<int> nums = convertArrayToVector(array, ARRAY_LENGTH(array)); Solution sol; cout << sol.containsNearbyDuplicate2(nums, 0); }
|
提交到 Leetcode,Accepted! :) 运行时间为 79ms。
注意上面程序的第 21 行,map.find 的时间复杂度为 O(logN),所以整个程序的时间复杂度为 O(NlogN)。
参考资料