54
54
55
55
<!-- 这里可写通用的实现逻辑 -->
56
56
57
- 动态规划求解。
57
+ ** 方法一:动态规划 **
58
58
59
59
定义 ` dp[i] ` 为以 ` nums[i] ` 结尾的最长子序列的长度,` dp[i] ` 初始化为 1(` i∈[0, n) ` )。即题目求的是 ` dp[i] ` (` i ∈[0, n-1] ` )的最大值。
60
60
61
- 状态转移方程为:
61
+ 状态转移方程为:` dp[i] = max(dp[j]) + 1 ` ,其中 ` 0≤j<i ` 且 ` nums[j]<nums[i] ` 。
62
62
63
- ` dp[i] = max(dp[j]) + 1 ` ,其中 ` 0≤j<i ` 且 ` nums[j]<nums[i] ` 。
63
+ 时间复杂度 O(n²)。
64
+
65
+ ** 方法二:树状数组**
66
+
67
+ 树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
68
+
69
+ 1 . ** 单点更新** ` update(x, delta) ` : 把序列 x 位置的数加上一个值 delta;
70
+ 1 . ** 前缀和查询** ` query(x) ` :查询序列 ` [1,...x] ` 区间的区间和,即位置 x 的前缀和。
71
+
72
+ 这两个操作的时间复杂度均为 ` O(log n) ` 。当数的范围比较大时,需要进行离散化,即先进行去重并排序,然后对每个数字进行编号。
73
+
74
+ 本题我们使用树状数组 ` tree[x] ` 来维护以 x 结尾的最长上升子序列的长度。
75
+
76
+ 时间复杂度 O(nlogn)。
77
+
78
+ ``` python
79
+ def update (x , val ):
80
+ while x <= n:
81
+ c[x] = max (c[x], val)
82
+ x += lowbit(x)
83
+
84
+
85
+ def query (x ):
86
+ s = 0
87
+ while x > 0 :
88
+ s = max (s, c[x])
89
+ x -= lowbit(x)
90
+ return s
91
+ ```
64
92
65
93
<!-- tabs:start -->
66
94
67
95
### ** Python3**
68
96
69
97
<!-- 这里可写当前语言的特殊实现逻辑 -->
70
98
99
+ 动态规划:
100
+
71
101
``` python
72
102
class Solution :
73
103
def lengthOfLIS (self , nums : List[int ]) -> int :
@@ -80,10 +110,51 @@ class Solution:
80
110
return max (dp)
81
111
```
82
112
113
+ 树状数组:
114
+
115
+ ``` python
116
+ class BinaryIndexedTree :
117
+ def __init__ (self , n ):
118
+ self .n = n
119
+ self .c = [0 ] * (n + 1 )
120
+
121
+ @ staticmethod
122
+ def lowbit (x ):
123
+ return x & - x
124
+
125
+ def update (self , x , val ):
126
+ while x <= self .n:
127
+ self .c[x] = max (self .c[x], val)
128
+ x += BinaryIndexedTree.lowbit(x)
129
+
130
+ def query (self , x ):
131
+ s = 0
132
+ while x:
133
+ s = max (s, self .c[x])
134
+ x -= BinaryIndexedTree.lowbit(x)
135
+ return s
136
+
137
+
138
+ class Solution :
139
+ def lengthOfLIS (self , nums : List[int ]) -> int :
140
+ s = sorted (set (nums))
141
+ m = {v: i for i, v in enumerate (s, 1 )}
142
+ tree = BinaryIndexedTree(len (m))
143
+ ans = 1
144
+ for v in nums:
145
+ x = m[v]
146
+ t = tree.query(x - 1 ) + 1
147
+ ans = max (ans, t)
148
+ tree.update(x, t)
149
+ return ans
150
+ ```
151
+
83
152
### ** Java**
84
153
85
154
<!-- 这里可写当前语言的特殊实现逻辑 -->
86
155
156
+ 动态规划:
157
+
87
158
``` java
88
159
class Solution {
89
160
public int lengthOfLIS (int [] nums ) {
@@ -104,8 +175,67 @@ class Solution {
104
175
}
105
176
```
106
177
178
+ 树状数组:
179
+
180
+ ``` java
181
+ class Solution {
182
+ public int lengthOfLIS (int [] nums ) {
183
+ TreeSet<Integer > ts = new TreeSet ();
184
+ for (int v : nums) {
185
+ ts. add(v);
186
+ }
187
+ int idx = 1 ;
188
+ Map<Integer , Integer > m = new HashMap<> ();
189
+ for (int v : ts) {
190
+ m. put(v, idx++ );
191
+ }
192
+ BinaryIndexedTree tree = new BinaryIndexedTree (m. size());
193
+ int ans = 1 ;
194
+ for (int v : nums) {
195
+ int x = m. get(v);
196
+ int t = tree. query(x - 1 ) + 1 ;
197
+ ans = Math . max(ans, t);
198
+ tree. update(x, t);
199
+ }
200
+ return ans;
201
+ }
202
+ }
203
+
204
+ class BinaryIndexedTree {
205
+ private int n;
206
+ private int [] c;
207
+
208
+ public BinaryIndexedTree (int n ) {
209
+ this . n = n;
210
+ c = new int [n + 1 ];
211
+ }
212
+
213
+ public void update (int x , int val ) {
214
+ while (x <= n) {
215
+ c[x] = Math . max(c[x], val);
216
+ x += lowbit(x);
217
+ }
218
+ }
219
+
220
+ public int query (int x ) {
221
+ int s = 0 ;
222
+ while (x > 0 ) {
223
+ s = Math . max(s, c[x]);
224
+ x -= lowbit(x);
225
+ }
226
+ return s;
227
+ }
228
+
229
+ public static int lowbit (int x ) {
230
+ return x & - x;
231
+ }
232
+ }
233
+ ```
234
+
107
235
### ** TypeScript**
108
236
237
+ 动态规划:
238
+
109
239
``` ts
110
240
function lengthOfLIS(nums : number []): number {
111
241
let n = nums .length ;
@@ -123,6 +253,8 @@ function lengthOfLIS(nums: number[]): number {
123
253
124
254
### ** C++**
125
255
256
+ 动态规划:
257
+
126
258
``` cpp
127
259
class Solution {
128
260
public:
@@ -141,8 +273,64 @@ public:
141
273
};
142
274
```
143
275
276
+ 树状数组:
277
+
278
+ ```cpp
279
+ class BinaryIndexedTree {
280
+ public:
281
+ int n;
282
+ vector<int> c;
283
+
284
+ BinaryIndexedTree(int _n): n(_n), c(_n + 1){}
285
+
286
+ void update(int x, int val) {
287
+ while (x <= n)
288
+ {
289
+ c[x] = max(c[x], val);
290
+ x += lowbit(x);
291
+ }
292
+ }
293
+
294
+ int query(int x) {
295
+ int s = 0;
296
+ while (x > 0)
297
+ {
298
+ s = max(s, c[x]);
299
+ x -= lowbit(x);
300
+ }
301
+ return s;
302
+ }
303
+
304
+ int lowbit(int x) {
305
+ return x & -x;
306
+ }
307
+ };
308
+
309
+ class Solution {
310
+ public:
311
+ int lengthOfLIS(vector<int>& nums) {
312
+ set<int> s(nums.begin(), nums.end());
313
+ int idx = 1;
314
+ unordered_map<int, int> m;
315
+ for (int v : s) m[v] = idx++;
316
+ BinaryIndexedTree* tree = new BinaryIndexedTree(m.size());
317
+ int ans = 1;
318
+ for (int v : nums)
319
+ {
320
+ int x = m[v];
321
+ int t = tree->query(x - 1) + 1;
322
+ ans = max(ans, t);
323
+ tree->update(x, t);
324
+ }
325
+ return ans;
326
+ }
327
+ };
328
+ ```
329
+
144
330
### ** Go**
145
331
332
+ 动态规划:
333
+
146
334
``` go
147
335
func lengthOfLIS (nums []int ) int {
148
336
n := len (nums)
@@ -169,6 +357,71 @@ func max(a, b int) int {
169
357
}
170
358
```
171
359
360
+ 树状数组:
361
+
362
+ ``` go
363
+ type BinaryIndexedTree struct {
364
+ n int
365
+ c []int
366
+ }
367
+
368
+ func newBinaryIndexedTree (n int ) *BinaryIndexedTree {
369
+ c := make ([]int , n+1 )
370
+ return &BinaryIndexedTree{n, c}
371
+ }
372
+
373
+ func (this *BinaryIndexedTree ) lowbit (x int ) int {
374
+ return x & -x
375
+ }
376
+
377
+ func (this *BinaryIndexedTree ) update (x , val int ) {
378
+ for x <= this.n {
379
+ if this.c [x] < val {
380
+ this.c [x] = val
381
+ }
382
+ x += this.lowbit (x)
383
+ }
384
+ }
385
+
386
+ func (this *BinaryIndexedTree ) query (x int ) int {
387
+ s := 0
388
+ for x > 0 {
389
+ if s < this.c [x] {
390
+ s = this.c [x]
391
+ }
392
+ x -= this.lowbit (x)
393
+ }
394
+ return s
395
+ }
396
+
397
+ func lengthOfLIS (nums []int ) int {
398
+ s := make (map [int ]bool )
399
+ for _ , v := range nums {
400
+ s[v] = true
401
+ }
402
+ var t []int
403
+ for v , _ := range s {
404
+ t = append (t, v)
405
+ }
406
+ sort.Ints (t)
407
+ m := make (map [int ]int )
408
+ for i , v := range t {
409
+ m[v] = i + 1
410
+ }
411
+ ans := 1
412
+ tree := newBinaryIndexedTree (len (m))
413
+ for _ , v := range nums {
414
+ x := m[v]
415
+ t := tree.query (x-1 ) + 1
416
+ if ans < t {
417
+ ans = t
418
+ }
419
+ tree.update (x, t)
420
+ }
421
+ return ans
422
+ }
423
+ ```
424
+
172
425
### ** ...**
173
426
174
427
```
0 commit comments