Skip to content

Commit ece6e8a

Browse files
committed
feat: add solutions to lc problem: No.0300
No.0300.Longest Increasing Subsequence
1 parent a4c856d commit ece6e8a

File tree

8 files changed

+665
-57
lines changed

8 files changed

+665
-57
lines changed

solution/0300-0399/0300.Longest Increasing Subsequence/README.md

Lines changed: 256 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,20 +54,50 @@
5454

5555
<!-- 这里可写通用的实现逻辑 -->
5656

57-
动态规划求解。
57+
**方法一:动态规划**
5858

5959
定义 `dp[i]` 为以 `nums[i]` 结尾的最长子序列的长度,`dp[i]` 初始化为 1(`i∈[0, n)`)。即题目求的是 `dp[i]``i ∈[0, n-1]`)的最大值。
6060

61-
状态转移方程为:
61+
状态转移方程为:`dp[i] = max(dp[j]) + 1`,其中 `0≤j<i``nums[j]<nums[i]`
6262

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+
```
6492

6593
<!-- tabs:start -->
6694

6795
### **Python3**
6896

6997
<!-- 这里可写当前语言的特殊实现逻辑 -->
7098

99+
动态规划:
100+
71101
```python
72102
class Solution:
73103
def lengthOfLIS(self, nums: List[int]) -> int:
@@ -80,10 +110,51 @@ class Solution:
80110
return max(dp)
81111
```
82112

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+
83152
### **Java**
84153

85154
<!-- 这里可写当前语言的特殊实现逻辑 -->
86155

156+
动态规划:
157+
87158
```java
88159
class Solution {
89160
public int lengthOfLIS(int[] nums) {
@@ -104,8 +175,67 @@ class Solution {
104175
}
105176
```
106177

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+
107235
### **TypeScript**
108236

237+
动态规划:
238+
109239
```ts
110240
function lengthOfLIS(nums: number[]): number {
111241
let n = nums.length;
@@ -123,6 +253,8 @@ function lengthOfLIS(nums: number[]): number {
123253

124254
### **C++**
125255

256+
动态规划:
257+
126258
```cpp
127259
class Solution {
128260
public:
@@ -141,8 +273,64 @@ public:
141273
};
142274
```
143275
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+
144330
### **Go**
145331

332+
动态规划:
333+
146334
```go
147335
func lengthOfLIS(nums []int) int {
148336
n := len(nums)
@@ -169,6 +357,71 @@ func max(a, b int) int {
169357
}
170358
```
171359

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+
172425
### **...**
173426

174427
```

0 commit comments

Comments
 (0)