---
# System prepended metadata

title: '300. 最长递增子序列  Longest Increasing Subsequence [DP] [Medium]'

---

# 300. 最长递增子序列  Longest Increasing Subsequence [DP] [Medium]
給你一個整數數組 nums ，找到其中最長嚴格遞增子序列的長度。

子序列 是由數組派生而來的序列，刪除（或不刪除）數組中的元素而不改變其余元素的順序。例如，[3,6,2,7] 是數組 [0,3,1,6,2,2,7] 的子序列。

 
示例 1：

```
輸入：nums = [10,9,2,5,3,7,101,18]
輸出：4
解釋：最長遞增子序列是 [2,3,7,101]，因此長度為 4 。
```
示例 2：

```
輸入：nums = [0,1,0,3,2,3]
輸出：4
```
示例 3：

```
輸入：nums = [7,7,7,7,7,7,7]
輸出：1
```
 
 題解思路：
 最長遞增子序列，已知一个序列 {S1, S2,...,Sn}，取出若干数组成新的序列 {Si1, Si2,..., Sim}，其中 i1、i2 ... im 保持递增，新序列為原序列的**子序列**


如果在子序列中，当下标 ix > iy 时，Six > Siy，称子序列为原序列的一个 **递增子序列** 。

定義一個數組dp[n]是儲存最長遞增子序列的長度，dp[i]為下標為i的最長遞增子序列的長度，整個數組最長的那個遞增子序列就是要找的dp[n]

因此 dp[n] = max{dp[i]+1} | Si < Sn && i < n 。

![](https://i.imgur.com/VgSrEVc.png)

```java=
// Dynamic programming.
class Solution {
    public int lengthOfLIS(int[] nums) {
        if(nums.length == 0) return 0;
        int[] dp = new int[nums.length];
        int res = 0;
        Arrays.fill(dp, 1);
        for(int i = 0; i < nums.length; i++) {
            for(int j = 0; j < i; j++) {
                if(nums[j] < nums[i]) dp[i] = Math.max(dp[i], dp[j] + 1);
            }
            res = Math.max(res, dp[i]);
        }
        return res;
    }
}

```
