52
52
53
53
** 方法一:单调栈**
54
54
55
- ** 方法二:树状数组 **
55
+ 我们可以枚举从右往左枚举整数 $nums [ i ] $,并维护一个单调栈,栈中的元素从栈底到栈顶单调递减。维护一个变量 $vk$,表示 $nums [ i ] $ 右侧且小于 $nums [ i ] $ 的最大值。初始时,$vk$ 的值为 $-\infty$。
56
56
57
- 树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
57
+ 我们从右往左遍历数组,对于遍历到的每个元素 $nums [ i ] $,如果 $nums [ i ] $ 小于 $vk$,则说明我们找到了一个满足 $nums [ i ] \lt nums [ k ] \lt nums [ j ] $ 的三元组,返回 ` true ` 。否则,如果栈顶元素小于 $nums [ i ] $,则我们循环将栈顶元素出栈,并且更新 $vk$ 的值为出栈元素,直到栈为空或者栈顶元素大于等于 $nums [ i ] $。最后,我们将 $nums [ i ] $ 入栈。
58
58
59
- 1 . ** 单点更新** ` update(x, delta) ` : 把序列 x 位置的数加上一个值 delta;
60
- 1 . ** 前缀和查询** ` query(x) ` :查询序列 ` [1,...x] ` 区间的区间和,即位置 x 的前缀和。
59
+ 如果遍历结束后仍未找到满足条件的三元组,说明不存在这样的三元组,返回 ` false ` 。
61
60
62
- 这两个操作的时间复杂度均为 $O(\log n)$。
61
+ 时间复杂度 $O(n)$,空间复杂度 $O( n)$。其中 $n$ 为数组的长度 。
63
62
64
- 树状数组最基本的功能就是求比某点 x 小的点的个数(这里的比较是抽象的概念,可以是数的大小、坐标的大小、质量的大小等等)。
63
+ ** 方法二:离散化 + 树状数组 **
65
64
66
- 比如给定数组 ` a[5] = {2, 5, 3, 4, 1} ` ,求 ` b[i] = 位置 i 左边小于等于 a [i] 的数的个数 ` 。对于此例, ` b[5] = {0, 1, 1, 2, 0} ` 。
65
+ 我们可以用树状数组维护比某个数小的元素的个数,用一个数组 $left$ 记录 $nums [ i] $ 左侧的最小值 。
67
66
68
- 解决方案是直接遍历数组,每个位置先求出 ` query(a[i]) ` ,然后再修改树状数组 ` update(a[i], 1) ` 即可。当数的范围比较大时,需要进行离散化,即先进行去重并排序,然后对每个数字进行编号。
67
+ 我们从右往左遍历数组,对于遍历到的每个元素 $nums[ i] $,我们将 $nums[ i] $ 离散化为一个整数 $x$,将 $left[ i] $ 离散化为一个整数 $y$,如果此时 $x \gt y$,并且树状数组中存在比 $y$ 大但比 $x$ 小的元素,则说明存在满足 $nums[ i] \lt nums[ k] \lt nums[ j] $ 的三元组,返回 ` true ` 。否则,我们将 $nums[ i] $ 的离散化结果 $x$ 更新到树状数组中。
68
+
69
+ 如果遍历结束后仍未找到满足条件的三元组,说明不存在这样的三元组,返回 ` false ` 。
70
+
71
+ 时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。
69
72
70
73
<!-- tabs:start -->
71
74
@@ -117,7 +120,7 @@ class Solution:
117
120
for i in range (n - 1 , - 1 , - 1 ):
118
121
x = bisect_left(s, nums[i]) + 1
119
122
y = bisect_left(s, left[i]) + 1
120
- if x > y and ( tree.query(x - 1 ) - tree.query(y) > 0 ):
123
+ if x > y and tree.query(x - 1 ) > tree.query(y):
121
124
return True
122
125
tree.update(x, 1 )
123
126
return False
@@ -191,7 +194,7 @@ class Solution {
191
194
for (int i = n - 1 ; i >= 0 ; -- i) {
192
195
int x = search(s, m, nums[i]);
193
196
int y = search(s, m, left[i]);
194
- if (x > y && tree. query(x - 1 ) - tree. query(y) > 0 ) {
197
+ if (x > y && tree. query(x - 1 ) > tree. query(y)) {
195
198
return true ;
196
199
}
197
200
tree. update(x, 1 );
@@ -237,6 +240,61 @@ public:
237
240
};
238
241
```
239
242
243
+ ```cpp
244
+ class BinaryIndexedTree {
245
+ public:
246
+ BinaryIndexedTree(int n) {
247
+ this->n = n;
248
+ this->c = vector<int>(n + 1, 0);
249
+ }
250
+
251
+ void update(int x, int val) {
252
+ while (x <= n) {
253
+ c[x] += val;
254
+ x += x & -x;
255
+ }
256
+ }
257
+
258
+ int query(int x) {
259
+ int s = 0;
260
+ while (x > 0) {
261
+ s += c[x];
262
+ x -= x & -x;
263
+ }
264
+ return s;
265
+ }
266
+
267
+ private:
268
+ int n;
269
+ vector<int> c;
270
+ };
271
+
272
+ class Solution {
273
+ public:
274
+ bool find132pattern(vector<int>& nums) {
275
+ vector<int> s = nums;
276
+ sort(s.begin(), s.end());
277
+ s.erase(unique(s.begin(), s.end()), s.end());
278
+ BinaryIndexedTree tree(s.size());
279
+ int n = nums.size();
280
+ int left[n + 1];
281
+ memset(left, 63, sizeof(left));
282
+ for (int i = 0; i < n; ++i) {
283
+ left[i + 1] = min(left[i], nums[i]);
284
+ }
285
+ for (int i = nums.size() - 1; ~i; --i) {
286
+ int x = lower_bound(s.begin(), s.end(), nums[i]) - s.begin() + 1;
287
+ int y = lower_bound(s.begin(), s.end(), left[i]) - s.begin() + 1;
288
+ if (x > y && tree.query(x - 1) > tree.query(y)) {
289
+ return true;
290
+ }
291
+ tree.update(x, 1);
292
+ }
293
+ return false;
294
+ }
295
+ };
296
+ ```
297
+
240
298
### ** Go**
241
299
242
300
``` go
@@ -257,6 +315,69 @@ func find132pattern(nums []int) bool {
257
315
}
258
316
```
259
317
318
+ ``` go
319
+ type BinaryIndexedTree struct {
320
+ n int
321
+ c []int
322
+ }
323
+
324
+ func newBinaryIndexedTree (n int ) *BinaryIndexedTree {
325
+ c := make ([]int , n+1 )
326
+ return &BinaryIndexedTree{n, c}
327
+ }
328
+
329
+ func (this *BinaryIndexedTree ) update (x , val int ) {
330
+ for x <= this.n {
331
+ this.c [x] += val
332
+ x += x & -x
333
+ }
334
+ }
335
+
336
+ func (this *BinaryIndexedTree ) query (x int ) int {
337
+ s := 0
338
+ for x > 0 {
339
+ s += this.c [x]
340
+ x -= x & -x
341
+ }
342
+ return s
343
+ }
344
+
345
+ func find132pattern (nums []int ) bool {
346
+ n := len (nums)
347
+ s := make ([]int , n)
348
+ left := make ([]int , n+1 )
349
+ left[0 ] = 1 << 30
350
+ copy (s, nums)
351
+ sort.Ints (s)
352
+ m := 0
353
+ for i := 0 ; i < n; i++ {
354
+ left[i+1 ] = min (left[i], nums[i])
355
+ if i == 0 || s[i] != s[i-1 ] {
356
+ s[m] = s[i]
357
+ m++
358
+ }
359
+ }
360
+ s = s[:m]
361
+ tree := newBinaryIndexedTree (m)
362
+ for i := n - 1 ; i >= 0 ; i-- {
363
+ x := sort.SearchInts (s, nums[i]) + 1
364
+ y := sort.SearchInts (s, left[i]) + 1
365
+ if x > y && tree.query (x-1 ) > tree.query (y) {
366
+ return true
367
+ }
368
+ tree.update (x, 1 )
369
+ }
370
+ return false
371
+ }
372
+
373
+ func min (a , b int ) int {
374
+ if a < b {
375
+ return a
376
+ }
377
+ return b
378
+ }
379
+ ```
380
+
260
381
### ** TypeScript**
261
382
262
383
``` ts
@@ -276,6 +397,73 @@ function find132pattern(nums: number[]): boolean {
276
397
}
277
398
```
278
399
400
+ ``` ts
401
+ class BinaryIndextedTree {
402
+ n: number ;
403
+ c: number [];
404
+
405
+ constructor (n : number ) {
406
+ this .n = n ;
407
+ this .c = new Array (n + 1 ).fill (0 );
408
+ }
409
+
410
+ update(x : number , val : number ): void {
411
+ while (x <= this .n ) {
412
+ this .c [x ] += val ;
413
+ x += x & - x ;
414
+ }
415
+ }
416
+
417
+ query(x : number ): number {
418
+ let s = 0 ;
419
+ while (x ) {
420
+ s += this .c [x ];
421
+ x -= x & - x ;
422
+ }
423
+ return s ;
424
+ }
425
+ }
426
+
427
+ function find132pattern(nums : number []): boolean {
428
+ let s: number [] = [... nums ];
429
+ s .sort ((a , b ) => a - b );
430
+ const n = nums .length ;
431
+ const left: number [] = new Array (n + 1 ).fill (1 << 30 );
432
+ let m = 0 ;
433
+ for (let i = 0 ; i < n ; ++ i ) {
434
+ left [i + 1 ] = Math .min (left [i ], nums [i ]);
435
+ if (i == 0 || s [i ] != s [i - 1 ]) {
436
+ s [m ++ ] = s [i ];
437
+ }
438
+ }
439
+ s = s .slice (0 , m );
440
+ const tree = new BinaryIndextedTree (m );
441
+ for (let i = n - 1 ; i >= 0 ; -- i ) {
442
+ const x = search (s , nums [i ]);
443
+ const y = search (s , left [i ]);
444
+ if (x > y && tree .query (x - 1 ) > tree .query (y )) {
445
+ return true ;
446
+ }
447
+ tree .update (x , 1 );
448
+ }
449
+ return false ;
450
+ }
451
+
452
+ function search(nums : number [], x : number ): number {
453
+ let l = 0 ,
454
+ r = nums .length - 1 ;
455
+ while (l < r ) {
456
+ const mid = (l + r ) >> 1 ;
457
+ if (nums [mid ] >= x ) {
458
+ r = mid ;
459
+ } else {
460
+ l = mid + 1 ;
461
+ }
462
+ }
463
+ return l + 1 ;
464
+ }
465
+ ```
466
+
279
467
### ** Rust**
280
468
281
469
``` rust
0 commit comments