Skip to content

Commit 1a8fc8b

Browse files
committed
feat: add solutions to lc problem: No.0220
No.0219.Contains Duplicate II
1 parent 532b07d commit 1a8fc8b

File tree

7 files changed

+131
-71
lines changed

7 files changed

+131
-71
lines changed

solution/0200-0299/0219.Contains Duplicate II/README.md

+10
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,16 @@
4444

4545
<!-- 这里可写通用的实现逻辑 -->
4646

47+
**方法一:哈希表**
48+
49+
我们用哈希表存放最近遍历到的数以及对应的下标。
50+
51+
遍历数组 `nums`,对于当前遍历到的元素 $nums[i]$,如果在哈希表中存在,并且下标与当前元素的下标之差不超过 $k$,则返回 `true`,否则将当前元素加入哈希表中。
52+
53+
遍历结束后,返回 `false`
54+
55+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 `nums` 的长度。
56+
4757
<!-- tabs:start -->
4858

4959
### **Python3**

solution/0200-0299/0220.Contains Duplicate III/README.md

+52-18
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,13 @@
4545

4646
<!-- 这里可写通用的实现逻辑 -->
4747

48-
“滑动窗口 + 有序集合”实现。
48+
**方法一:滑动窗口 + 有序集合**
49+
50+
维护一个大小为 $k$ 的滑动窗口,窗口中的元素保持有序。
51+
52+
遍历数组 `nums`,对于每个元素 $nums[i]$,我们在有序集合中查找第一个大于等于 $nums[i] - t$ 的元素,如果元素存在,并且该元素小于等于 $nums[i] + t$,说明找到了一对符合条件的元素,返回 `true`。否则,我们将 $nums[i]$ 插入到有序集合中,并且如果有序集合的大小超过了 $k$,我们需要将最早加入有序集合的元素删除。
53+
54+
时间复杂度 $O(n\times \log k)$,其中 $n$ 是数组 `nums` 的长度。对于每个元素,我们需要 $O(\log k)$ 的时间来查找有序集合中的元素,一共有 $n$ 个元素,因此总时间复杂度是 $O(n\times \log k)$。
4955

5056
<!-- tabs:start -->
5157

@@ -58,15 +64,15 @@ from sortedcontainers import SortedSet
5864

5965

6066
class Solution:
61-
def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:
67+
def containsNearbyAlmostDuplicate(self, nums: List[int], indexDiff: int, valueDiff: int) -> bool:
6268
s = SortedSet()
63-
for i, num in enumerate(nums):
64-
idx = s.bisect_left(num - t)
65-
if 0 <= idx < len(s) and s[idx] <= num + t:
69+
for i, v in enumerate(nums):
70+
j = s.bisect_left(v - valueDiff)
71+
if j < len(s) and s[j] <= v + valueDiff:
6672
return True
67-
s.add(num)
68-
if i >= k:
69-
s.remove(nums[i - k])
73+
s.add(v)
74+
if i >= indexDiff:
75+
s.remove(nums[i - indexDiff])
7076
return False
7177
```
7278

@@ -76,16 +82,16 @@ class Solution:
7682

7783
```java
7884
class Solution {
79-
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
85+
public boolean containsNearbyAlmostDuplicate(int[] nums, int indexDiff, int valueDiff) {
8086
TreeSet<Long> ts = new TreeSet<>();
8187
for (int i = 0; i < nums.length; ++i) {
82-
Long x = ts.ceiling((long) nums[i] - (long) t);
83-
if (x != null && x <= (long) nums[i] + (long) t) {
88+
Long x = ts.ceiling((long) nums[i] - (long) valueDiff);
89+
if (x != null && x <= (long) nums[i] + (long) valueDiff) {
8490
return true;
8591
}
8692
ts.add((long) nums[i]);
87-
if (i >= k) {
88-
ts.remove((long) nums[i - k]);
93+
if (i >= indexDiff) {
94+
ts.remove((long) nums[i - indexDiff]);
8995
}
9096
}
9197
return false;
@@ -98,13 +104,13 @@ class Solution {
98104
```cpp
99105
class Solution {
100106
public:
101-
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
107+
bool containsNearbyAlmostDuplicate(vector<int>& nums, int indexDiff, int valueDiff) {
102108
set<long> s;
103109
for (int i = 0; i < nums.size(); ++i) {
104-
auto it = s.lower_bound((long)nums[i] - t);
105-
if (it != s.end() && *it <= (long)nums[i] + t) return true;
106-
s.insert((long)nums[i]);
107-
if (i >= k) s.erase((long)nums[i - k]);
110+
auto it = s.lower_bound((long) nums[i] - valueDiff);
111+
if (it != s.end() && *it <= (long) nums[i] + valueDiff) return true;
112+
s.insert((long) nums[i]);
113+
if (i >= indexDiff) s.erase((long) nums[i - indexDiff]);
108114
}
109115
return false;
110116
}
@@ -137,6 +143,34 @@ func containsNearbyAlmostDuplicate(nums []int, k int, t int) bool {
137143
}
138144
```
139145

146+
### **C#**
147+
148+
```cs
149+
public class Solution {
150+
public bool ContainsNearbyAlmostDuplicate(int[] nums, int k, int t) {
151+
if (k <= 0 || t < 0) return false;
152+
var index = new SortedList<int, object>();
153+
for (int i = 0; i < nums.Length; ++i) {
154+
if (index.ContainsKey(nums[i])) {
155+
return true;
156+
}
157+
index.Add(nums[i], null);
158+
var j = index.IndexOfKey(nums[i]);
159+
if (j > 0 && (long)nums[i] - index.Keys[j - 1] <= t) {
160+
return true;
161+
}
162+
if (j < index.Count - 1 && (long)index.Keys[j + 1] - nums[i] <= t) {
163+
return true;
164+
}
165+
if (index.Count > k) {
166+
index.Remove(nums[i - k]);
167+
}
168+
}
169+
return false;
170+
}
171+
}
172+
```
173+
140174
### **...**
141175

142176
```

solution/0200-0299/0220.Contains Duplicate III/README_EN.md

+45-17
Original file line numberDiff line numberDiff line change
@@ -58,32 +58,32 @@ from sortedcontainers import SortedSet
5858

5959

6060
class Solution:
61-
def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:
61+
def containsNearbyAlmostDuplicate(self, nums: List[int], indexDiff: int, valueDiff: int) -> bool:
6262
s = SortedSet()
63-
for i, num in enumerate(nums):
64-
idx = s.bisect_left(num - t)
65-
if 0 <= idx < len(s) and s[idx] <= num + t:
63+
for i, v in enumerate(nums):
64+
j = s.bisect_left(v - valueDiff)
65+
if j < len(s) and s[j] <= v + valueDiff:
6666
return True
67-
s.add(num)
68-
if i >= k:
69-
s.remove(nums[i - k])
67+
s.add(v)
68+
if i >= indexDiff:
69+
s.remove(nums[i - indexDiff])
7070
return False
7171
```
7272

7373
### **Java**
7474

7575
```java
7676
class Solution {
77-
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
77+
public boolean containsNearbyAlmostDuplicate(int[] nums, int indexDiff, int valueDiff) {
7878
TreeSet<Long> ts = new TreeSet<>();
7979
for (int i = 0; i < nums.length; ++i) {
80-
Long x = ts.ceiling((long) nums[i] - (long) t);
81-
if (x != null && x <= (long) nums[i] + (long) t) {
80+
Long x = ts.ceiling((long) nums[i] - (long) valueDiff);
81+
if (x != null && x <= (long) nums[i] + (long) valueDiff) {
8282
return true;
8383
}
8484
ts.add((long) nums[i]);
85-
if (i >= k) {
86-
ts.remove((long) nums[i - k]);
85+
if (i >= indexDiff) {
86+
ts.remove((long) nums[i - indexDiff]);
8787
}
8888
}
8989
return false;
@@ -96,13 +96,13 @@ class Solution {
9696
```cpp
9797
class Solution {
9898
public:
99-
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
99+
bool containsNearbyAlmostDuplicate(vector<int>& nums, int indexDiff, int valueDiff) {
100100
set<long> s;
101101
for (int i = 0; i < nums.size(); ++i) {
102-
auto it = s.lower_bound((long)nums[i] - t);
103-
if (it != s.end() && *it <= (long)nums[i] + t) return true;
104-
s.insert((long)nums[i]);
105-
if (i >= k) s.erase((long)nums[i - k]);
102+
auto it = s.lower_bound((long) nums[i] - valueDiff);
103+
if (it != s.end() && *it <= (long) nums[i] + valueDiff) return true;
104+
s.insert((long) nums[i]);
105+
if (i >= indexDiff) s.erase((long) nums[i - indexDiff]);
106106
}
107107
return false;
108108
}
@@ -135,6 +135,34 @@ func containsNearbyAlmostDuplicate(nums []int, k int, t int) bool {
135135
}
136136
```
137137

138+
### **C#**
139+
140+
```cs
141+
public class Solution {
142+
public bool ContainsNearbyAlmostDuplicate(int[] nums, int k, int t) {
143+
if (k <= 0 || t < 0) return false;
144+
var index = new SortedList<int, object>();
145+
for (int i = 0; i < nums.Length; ++i) {
146+
if (index.ContainsKey(nums[i])) {
147+
return true;
148+
}
149+
index.Add(nums[i], null);
150+
var j = index.IndexOfKey(nums[i]);
151+
if (j > 0 && (long)nums[i] - index.Keys[j - 1] <= t) {
152+
return true;
153+
}
154+
if (j < index.Count - 1 && (long)index.Keys[j + 1] - nums[i] <= t) {
155+
return true;
156+
}
157+
if (index.Count > k) {
158+
index.Remove(nums[i - k]);
159+
}
160+
}
161+
return false;
162+
}
163+
}
164+
```
165+
138166
### **...**
139167

140168
```

solution/0200-0299/0220.Contains Duplicate III/Solution.cpp

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
class Solution {
22
public:
3-
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
3+
bool containsNearbyAlmostDuplicate(vector<int>& nums, int indexDiff, int valueDiff) {
44
set<long> s;
55
for (int i = 0; i < nums.size(); ++i) {
6-
auto it = s.lower_bound((long) nums[i] - t);
7-
if (it != s.end() && *it <= (long) nums[i] + t) return true;
6+
auto it = s.lower_bound((long) nums[i] - valueDiff);
7+
if (it != s.end() && *it <= (long) nums[i] + valueDiff) return true;
88
s.insert((long) nums[i]);
9-
if (i >= k) s.erase((long) nums[i - k]);
9+
if (i >= indexDiff) s.erase((long) nums[i - indexDiff]);
1010
}
1111
return false;
1212
}
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,23 @@
1-
// https://leetcode.com/problems/contains-duplicate-iii/
2-
3-
using System.Collections.Generic;
4-
5-
public partial class Solution
6-
{
7-
public bool ContainsNearbyAlmostDuplicate(int[] nums, int k, int t)
8-
{
9-
1+
public class Solution {
2+
public bool ContainsNearbyAlmostDuplicate(int[] nums, int k, int t) {
103
if (k <= 0 || t < 0) return false;
114
var index = new SortedList<int, object>();
12-
for (int i = 0; i < nums.Length; ++i)
13-
{
14-
if (index.ContainsKey(nums[i]))
15-
{
5+
for (int i = 0; i < nums.Length; ++i) {
6+
if (index.ContainsKey(nums[i])) {
167
return true;
178
}
189
index.Add(nums[i], null);
1910
var j = index.IndexOfKey(nums[i]);
20-
if (j > 0 && (long)nums[i] - index.Keys[j - 1] <= t)
21-
{
11+
if (j > 0 && (long)nums[i] - index.Keys[j - 1] <= t) {
2212
return true;
2313
}
24-
if (j < index.Count - 1 && (long)index.Keys[j + 1] - nums[i] <= t)
25-
{
14+
if (j < index.Count - 1 && (long)index.Keys[j + 1] - nums[i] <= t) {
2615
return true;
2716
}
28-
if (index.Count > k)
29-
{
17+
if (index.Count > k) {
3018
index.Remove(nums[i - k]);
3119
}
3220
}
3321
return false;
3422
}
35-
}
23+
}

solution/0200-0299/0220.Contains Duplicate III/Solution.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
class Solution {
2-
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
2+
public boolean containsNearbyAlmostDuplicate(int[] nums, int indexDiff, int valueDiff) {
33
TreeSet<Long> ts = new TreeSet<>();
44
for (int i = 0; i < nums.length; ++i) {
5-
Long x = ts.ceiling((long) nums[i] - (long) t);
6-
if (x != null && x <= (long) nums[i] + (long) t) {
5+
Long x = ts.ceiling((long) nums[i] - (long) valueDiff);
6+
if (x != null && x <= (long) nums[i] + (long) valueDiff) {
77
return true;
88
}
99
ts.add((long) nums[i]);
10-
if (i >= k) {
11-
ts.remove((long) nums[i - k]);
10+
if (i >= indexDiff) {
11+
ts.remove((long) nums[i - indexDiff]);
1212
}
1313
}
1414
return false;

solution/0200-0299/0220.Contains Duplicate III/Solution.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33

44
class Solution:
5-
def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:
5+
def containsNearbyAlmostDuplicate(self, nums: List[int], indexDiff: int, valueDiff: int) -> bool:
66
s = SortedSet()
7-
for i, num in enumerate(nums):
8-
idx = s.bisect_left(num - t)
9-
if 0 <= idx < len(s) and s[idx] <= num + t:
7+
for i, v in enumerate(nums):
8+
j = s.bisect_left(v - valueDiff)
9+
if j < len(s) and s[j] <= v + valueDiff:
1010
return True
11-
s.add(num)
12-
if i >= k:
13-
s.remove(nums[i - k])
11+
s.add(v)
12+
if i >= indexDiff:
13+
s.remove(nums[i - indexDiff])
1414
return False

0 commit comments

Comments
 (0)