Skip to content

Commit 46cce2a

Browse files
committed
feat: add solutions to lc problem: No.0456
No.0456.132 Pattern
1 parent dbcdccd commit 46cce2a

File tree

4 files changed

+572
-1
lines changed

4 files changed

+572
-1
lines changed

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

Lines changed: 239 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,22 @@
5050

5151
<!-- 这里可写通用的实现逻辑 -->
5252

53-
单调栈实现。
53+
**方法一:单调栈**
54+
55+
**方法二:树状数组**
56+
57+
树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
58+
59+
1. **单点更新** `update(x, delta)`: 把序列 x 位置的数加上一个值 delta;
60+
1. **前缀和查询** `query(x)`:查询序列 `[1,...x]` 区间的区间和,即位置 x 的前缀和。
61+
62+
这两个操作的时间复杂度均为 `O(log n)`
63+
64+
树状数组最基本的功能就是求比某点 x 小的点的个数(这里的比较是抽象的概念,可以是数的大小、坐标的大小、质量的大小等等)。
65+
66+
比如给定数组 `a[5] = {2, 5, 3, 4, 1}`,求 `b[i] = 位置 i 左边小于等于 a[i] 的数的个数`。对于此例,`b[5] = {0, 1, 1, 2, 0}`
67+
68+
解决方案是直接遍历数组,每个位置先求出 `query(a[i])`,然后再修改树状数组 `update(a[i], 1)` 即可。当数的范围比较大时,需要进行离散化,即先进行去重并排序,然后对每个数字进行编号。
5469

5570
<!-- tabs:start -->
5671

@@ -72,6 +87,47 @@ class Solution:
7287
return False
7388
```
7489

90+
```python
91+
class BinaryIndexedTree:
92+
def __init__(self, n):
93+
self.n = n
94+
self.c = [0] * (n + 1)
95+
96+
@staticmethod
97+
def lowbit(x):
98+
return x & -x
99+
100+
def update(self, x, delta):
101+
while x <= self.n:
102+
self.c[x] += delta
103+
x += BinaryIndexedTree.lowbit(x)
104+
105+
def query(self, x):
106+
s = 0
107+
while x:
108+
s += self.c[x]
109+
x -= BinaryIndexedTree.lowbit(x)
110+
return s
111+
112+
113+
class Solution:
114+
def find132pattern(self, nums: List[int]) -> bool:
115+
s = sorted(set(nums))
116+
m = {v: i for i, v in enumerate(s, 1)}
117+
n = len(m)
118+
tree = BinaryIndexedTree(n)
119+
for v in nums:
120+
tree.update(m[v], 1)
121+
mi = nums[0]
122+
for v in nums:
123+
tree.update(m[v], -1)
124+
# v 右侧存在 (mi, v - 1] 范围内的数字,说明符合 132
125+
if tree.query(m[v] - 1) - tree.query(m[mi]) > 0:
126+
return True
127+
mi = min(mi, v)
128+
return False
129+
```
130+
75131
### **Java**
76132

77133
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -95,6 +151,67 @@ class Solution {
95151
}
96152
```
97153

154+
```java
155+
class BinaryIndexedTree {
156+
private int n;
157+
private int[] c;
158+
159+
public BinaryIndexedTree(int n) {
160+
this.n = n;
161+
c = new int[n + 1];
162+
}
163+
164+
public void update(int x, int delta) {
165+
while (x <= n) {
166+
c[x] += delta;
167+
x += lowbit(x);
168+
}
169+
}
170+
171+
public int query(int x) {
172+
int s = 0;
173+
while (x > 0) {
174+
s += c[x];
175+
x -= lowbit(x);
176+
}
177+
return s;
178+
}
179+
180+
public static int lowbit(int x) {
181+
return x & -x;
182+
}
183+
}
184+
185+
class Solution {
186+
public boolean find132pattern(int[] nums) {
187+
TreeSet<Integer> ts = new TreeSet();
188+
for (int v : nums) {
189+
ts.add(v);
190+
}
191+
int idx = 1;
192+
Map<Integer, Integer> m = new HashMap<>();
193+
for (int v : ts) {
194+
m.put(v, idx++);
195+
}
196+
int n = m.size();
197+
BinaryIndexedTree tree = new BinaryIndexedTree(n);
198+
for (int v : nums) {
199+
tree.update(m.get(v), 1);
200+
}
201+
int mi = nums[0];
202+
for (int v : nums) {
203+
int x = m.get(v);
204+
tree.update(x, -1);
205+
if (tree.query(x - 1) - tree.query(m.get(mi)) > 0) {
206+
return true;
207+
}
208+
mi = Math.min(mi, v);
209+
}
210+
return false;
211+
}
212+
}
213+
```
214+
98215
### **TypeScript**
99216

100217
```ts
@@ -144,6 +261,127 @@ impl Solution {
144261
}
145262
```
146263

264+
### **C++**
265+
266+
```cpp
267+
class BinaryIndexedTree {
268+
public:
269+
int n;
270+
vector<int> c;
271+
272+
BinaryIndexedTree(int _n): n(_n), c(_n + 1){}
273+
274+
void update(int x, int delta) {
275+
while (x <= n)
276+
{
277+
c[x] += delta;
278+
x += lowbit(x);
279+
}
280+
}
281+
282+
int query(int x) {
283+
int s = 0;
284+
while (x > 0)
285+
{
286+
s += c[x];
287+
x -= lowbit(x);
288+
}
289+
return s;
290+
}
291+
292+
int lowbit(int x) {
293+
return x & -x;
294+
}
295+
};
296+
297+
class Solution {
298+
public:
299+
bool find132pattern(vector<int>& nums) {
300+
unordered_set<int> s(nums.begin(), nums.end());
301+
vector<int> alls(s.begin(), s.end());
302+
sort(alls.begin(), alls.end());
303+
unordered_map<int, int> m;
304+
int n = alls.size();
305+
for (int i = 0; i < n; ++i) m[alls[i]] = i + 1;
306+
BinaryIndexedTree* tree = new BinaryIndexedTree(n);
307+
for (int v : nums) tree->update(m[v], 1);
308+
int mi = nums[0];
309+
for (int v : nums)
310+
{
311+
tree->update(m[v], -1);
312+
if (tree->query(m[v] - 1) - tree->query(m[mi]) > 0) return true;
313+
mi = min(mi, v);
314+
}
315+
return false;
316+
}
317+
};
318+
```
319+
320+
### **Go**
321+
322+
```go
323+
type BinaryIndexedTree struct {
324+
n int
325+
c []int
326+
}
327+
328+
func newBinaryIndexedTree(n int) *BinaryIndexedTree {
329+
c := make([]int, n+1)
330+
return &BinaryIndexedTree{n, c}
331+
}
332+
333+
func (this *BinaryIndexedTree) lowbit(x int) int {
334+
return x & -x
335+
}
336+
337+
func (this *BinaryIndexedTree) update(x, delta int) {
338+
for x <= this.n {
339+
this.c[x] += delta
340+
x += this.lowbit(x)
341+
}
342+
}
343+
344+
func (this *BinaryIndexedTree) query(x int) int {
345+
s := 0
346+
for x > 0 {
347+
s += this.c[x]
348+
x -= this.lowbit(x)
349+
}
350+
return s
351+
}
352+
353+
func find132pattern(nums []int) bool {
354+
s := make(map[int]bool)
355+
for _, v := range nums {
356+
s[v] = true
357+
}
358+
var alls []int
359+
for v := range s {
360+
alls = append(alls, v)
361+
}
362+
sort.Ints(alls)
363+
m := make(map[int]int)
364+
for i, v := range alls {
365+
m[v] = i + 1
366+
}
367+
tree := newBinaryIndexedTree(len(m))
368+
for _, v := range nums {
369+
tree.update(m[v], 1)
370+
}
371+
mi := nums[0]
372+
for _, v := range nums {
373+
tree.update(m[v], -1)
374+
if tree.query(m[v]-1)-tree.query(m[mi]) > 0 {
375+
return true
376+
}
377+
if v < mi {
378+
mi = v
379+
}
380+
}
381+
return false
382+
}
383+
```
384+
147385
### **...**
148386

149387
```

0 commit comments

Comments
 (0)