1. 程式人生 > 實用技巧 >leetcode-300-最長上升子序列

leetcode-300-最長上升子序列

目錄


本題是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;
    }

你的鼓勵也是我創作的動力

打賞地址