leetcode筆記——300最長遞增子序列

題目:

給定一個無序的整數數組,找到其中最長上升子序列的長度。

示例:

輸入: [10,9,2,5,3,7,101,18]
輸出: 4
解釋: 最長的上升子序列是 [2,3,7,101],它的長度是 4。

說明:

    可能會有多種最長上升子序列的組合,你只需要輸出對應的長度即可。
    你算法的時間複雜度應該爲 O(n2) 。

進階: 你能將算法的時間複雜度降低到 O(n log n) 嗎?

思路:這個題是使用動態規劃.數組dp[n]用來表示以第n個數組元素結尾的最長的遞增子序列的長度。遞推公式是dp[n]=max(dp[i]+1,1).其中需要遍歷所有下標小於n 的數組元素。這種思路的時間複雜度是O(n^2)。

這個題我剛開始就想簡單了,以爲值比較它的前一個就行,實際上需要比較下標比n小的所有的元素。

除此之外還可以使用二分法將複雜度降低到O(nlogn).代碼入以下代碼1.數組tail[n]表示長度爲n+1的最長子序列最後的一個數字。我自己寫代碼的時候,把二分查找int mid = l + (h - l) / 2;中的l寫成了1.。。。。。。

代碼:

class Solution {
    
  public int lengthOfLIS(int[] nums) {
        if(nums==null||nums.length==0)
            return 0;
        if(nums.length==1)
            return 1;
        int n=nums.length;
        int []dp=new int[n];
        for(int i=0;i<n;i++){
            int max=1;
            for(int j=0;j<i;j++){
               if(nums[i]>nums[j]){
                max=Math.max(dp[j]+1,max);
            }
               
            }
             dp[i]=max;//剛開始的時候我把這個寫在j的循環裏面了
        }
        int tem=0;
        for(int i=0;i<n;i++){
            tem=Math.max(tem,dp[i]);
        }
        return tem;
        
    }
}

代碼1:

class Solution {
    public int lengthOfLIS(int[] nums) {
int n = nums.length;
int[] tails = new int[n];
int len = 0;
for (int num : nums) {
int index = binarySearch(tails, len, num);
tails[index] = num;
if (index == len) {
len++;
}
}
return len;
}
private int binarySearch(int[] tails, int len, int key) {
int l = 0, h = len;
while (l < h) {
int mid = l + (h - l) / 2;
if (tails[mid] == key) {
return mid;
} else if (tails[mid] > key) {
h = mid;
} else {
l = mid + 1;
}
}
return l;
}
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章