leetcode-300-最長上升子序列
阿新 • • 發佈:2020-07-19
目錄
- Posted by 微博@Yangsc_o
- 原創文章,版權宣告:自由轉載-非商用-非衍生-保持署名 | Creative Commons BY-NC-ND 3.0
本題是leetcode,地址:300. 最長上升子序列
題目
給定一個無序的整數陣列,找到其中最長上升子序列的長度。
示例:
輸入: [10,9,2,5,3,7,101,18]
輸出: 4
解釋: 最長的上升子序列是 [2,3,7,101],它的長度是 4。
說明:可能會有多種最長上升子序列的組合,你只需要輸出對應的長度即可。
你演算法的時間複雜度應該為 O(n2) 。
進階: 你能將演算法的時間複雜度降低到 O(n log n) 嗎?
分析
如果nums[i] 陣列中第i個元素的最長子序列結果是v1,那麼下一個nums[i + 1]是可以參考nums[i]序列的值的結果的v1的,如果nums[i + 1] > nums[i] 那麼最子序列就可以+1;否則相等;
類似這種下一個結算結果可以參考上一個結果的題目,可以考慮使用動態規劃解決,解題步驟是:
- 思考狀態:定義 dp[i]dp[i] 為考慮前 i個元素,以第 i個數字結尾的最長上升子序列的長度,注意 nums[i] 必須被選取。
- 思考狀態轉移方程 :
dp[i]=max(dp[j])+1,其中0≤j<i且num[j]<num[i]
- 思考初始化:每一個nums[j],最短的子序列都是1,即dp[i] = 1;
- 思考輸出:
max(dp[i]),其中0≤i<n
code
public int lengthOfLIS(int[] nums) { // dp[i] = 1; int[] dp = new int[nums.length]; Arrays.fill(dp, 1); int res = 0; for (int i = 0; i < nums.length; i++) { // 計算dp[i]的條件,在已經計算過的dp陣列中找,如果num[i]>num[j],則取dp[j]+1的值, // 使用Math.max函式原因是覆蓋上一次比較的結果; for (int j = 0; j < i; j++) { if (nums[i] > nums[j]) { dp[i] = Math.max(dp[i], dp[j] + 1); } } if (dp[i] > res) { res = dp[i]; } } return res; }