Skip to content

Commit cfc4025

Browse files
committed
feat: add solutions to lc problem: No.0456
No.0456.132 Pattern
1 parent b3b1374 commit cfc4025

File tree

5 files changed

+385
-15
lines changed

5 files changed

+385
-15
lines changed

solution/0400-0499/0456.132 Pattern/README.md

Lines changed: 198 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -52,20 +52,23 @@
5252

5353
**方法一:单调栈**
5454

55-
**方法二:树状数组**
55+
我们可以枚举从右往左枚举整数 $nums[i]$,并维护一个单调栈,栈中的元素从栈底到栈顶单调递减。维护一个变量 $vk$,表示 $nums[i]$ 右侧且小于 $nums[i]$ 的最大值。初始时,$vk$ 的值为 $-\infty$。
5656

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]$ 入栈。
5858

59-
1. **单点更新** `update(x, delta)`: 把序列 x 位置的数加上一个值 delta;
60-
1. **前缀和查询** `query(x)`:查询序列 `[1,...x]` 区间的区间和,即位置 x 的前缀和。
59+
如果遍历结束后仍未找到满足条件的三元组,说明不存在这样的三元组,返回 `false`
6160

62-
这两个操作的时间复杂度均为 $O(\log n)$。
61+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度
6362

64-
树状数组最基本的功能就是求比某点 x 小的点的个数(这里的比较是抽象的概念,可以是数的大小、坐标的大小、质量的大小等等)。
63+
**方法二:离散化 + 树状数组**
6564

66-
比如给定数组 `a[5] = {2, 5, 3, 4, 1}`,求 `b[i] = 位置 i 左边小于等于 a[i] 的数的个数`。对于此例,`b[5] = {0, 1, 1, 2, 0}`
65+
我们可以用树状数组维护比某个数小的元素的个数,用一个数组 $left$ 记录 $nums[i]$ 左侧的最小值
6766

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$ 为数组的长度。
6972

7073
<!-- tabs:start -->
7174

@@ -117,7 +120,7 @@ class Solution:
117120
for i in range(n - 1, -1, -1):
118121
x = bisect_left(s, nums[i]) + 1
119122
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):
121124
return True
122125
tree.update(x, 1)
123126
return False
@@ -191,7 +194,7 @@ class Solution {
191194
for (int i = n - 1; i >= 0; --i) {
192195
int x = search(s, m, nums[i]);
193196
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)) {
195198
return true;
196199
}
197200
tree.update(x, 1);
@@ -237,6 +240,61 @@ public:
237240
};
238241
```
239242
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+
240298
### **Go**
241299

242300
```go
@@ -257,6 +315,69 @@ func find132pattern(nums []int) bool {
257315
}
258316
```
259317

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+
260381
### **TypeScript**
261382

262383
```ts
@@ -276,6 +397,73 @@ function find132pattern(nums: number[]): boolean {
276397
}
277398
```
278399

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+
279467
### **Rust**
280468

281469
```rust

0 commit comments

Comments
 (0)