45
45
46
46
<!-- 这里可写通用的实现逻辑 -->
47
47
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)$。
49
55
50
56
<!-- tabs:start -->
51
57
@@ -58,15 +64,15 @@ from sortedcontainers import SortedSet
58
64
59
65
60
66
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 :
62
68
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 :
66
72
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 ])
70
76
return False
71
77
```
72
78
@@ -76,16 +82,16 @@ class Solution:
76
82
77
83
``` java
78
84
class Solution {
79
- public boolean containsNearbyAlmostDuplicate (int [] nums , int k , int t ) {
85
+ public boolean containsNearbyAlmostDuplicate (int [] nums , int indexDiff , int valueDiff ) {
80
86
TreeSet<Long > ts = new TreeSet<> ();
81
87
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 ) {
84
90
return true ;
85
91
}
86
92
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 ]);
89
95
}
90
96
}
91
97
return false ;
@@ -98,13 +104,13 @@ class Solution {
98
104
``` cpp
99
105
class Solution {
100
106
public:
101
- bool containsNearbyAlmostDuplicate(vector<int >& nums, int k , int t ) {
107
+ bool containsNearbyAlmostDuplicate(vector<int >& nums, int indexDiff , int valueDiff ) {
102
108
set<long > s;
103
109
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 ] );
108
114
}
109
115
return false;
110
116
}
@@ -137,6 +143,34 @@ func containsNearbyAlmostDuplicate(nums []int, k int, t int) bool {
137
143
}
138
144
```
139
145
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
+
140
174
### ** ...**
141
175
142
176
```
0 commit comments