Leetcode 300 最長上公升子串行

2021-09-02 01:54:44 字數 2103 閱讀 5739

給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。

示例:

輸入:[10,9,2,5,3,7,101,18]輸出:4解釋:最長的上公升子串行是[2,3,7,101],它的長度是4
說明:高階:你能將演算法的時間複雜度降低到 o(n log n) 嗎?

解題思路:

1. 普通演算法

動態規劃。假設陣列的前n個數的所有上公升子串行是vector> data。第n+1個數將會對data產生影響。1. 如果data[i-1].back()後來一想,將nums[n+1]加入data的所有可能序列的末端,這個操作有很大的改進空間,因為nums[n+1]出現之後,以nums[n+1]結尾的最長公升序是確定的而且是唯一的,取決於data中公升序列末端小於nums[n+1]的最長乙個,按照這個想法就可以很好地解決上述的記憶體不足的現象。

很顯然data這個結構已經不適用了,改用可以自動排序的雜湊容器mapmp。其中容器的key代表數字nums,val代表當前以數字nums結尾出現的最長公升序列。當遇到nums[n+1]時,只需訪問key比nums[n+1]小的pair,在這些key中找乙個val最大的,然後當前nums[n+1]結尾的最大公升序長度即是val+1。如果沒有比nums[n+1]跟小的key,令nums[n+1]=1。如此,mp.size()<=nums.size(),取決於nums中不重複元素的個數,空間複雜度o(n)。時間複雜度o(n)-o(n^2)之間。已經滿足了題目要求。

事實上,這個演算法測試時間24ms,擊敗48%,仍有改進的空間。

2. 高階演算法

動態規劃,二分查詢。假設vectordata是前n個數查詢得到的最長公升序列。當nums[n+1]出現時,可能有以下三種情況:

nums[n+1]是data中的乙個數,那麼nums[n+1]不會影響原有的公升序列。

nums[n+1]恰好小於data[i],那麼data[i]=nums[n+1]。原有的公升序列長度不變,只需要理解為什麼更新data[i]的值。我們假設最終結果裡n+1之後公升序列是n_val,如果滿足(data[i],n_val)是公升序,那麼(nums[n+1],n_val)也必然是公升序,這個時候講nums[n+1]替換data[i]這一步是否存在不重要,可有可無,因為求解的是長度。如果不滿足(data[i],n_val)是公升序,那麼,必須替將data[i]換nums[n+1],(nums[n+1],n_val)才是公升序。綜上,應該替換,但是由此可知,這這麼一來,想要求解公升序列是什麼就難了。

剩下只可能是nums[n+1]大於data中的最後乙個數,在末尾追加即可。

以上的查詢,都用二分查詢,特殊之處在於返回1,2,3三種情況。

這樣一來時間複雜度就成了o(n)-o(nlogn),空間複雜度為o(n)。

普通解法:

LeetCode300 最長上公升子串行

給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。示例 輸入 10,9,2,5,3,7,101,18 輸出 4解釋 最長的上公升子串行是 2,3,7,101 它的長度是4。說明 題目分析 方法一 動態規劃,用dp i 表示以nums i 結尾的最長上公升子串行。那麼如何求dp i 呢,只要看n...

leetcode 300 最長上公升子串行

給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。示例 輸入 10,9,2,5,3,7,101,18 輸出 4解釋 最長的上公升子串行是 2,3,7,101 它的長度是4。說明 高階 你能將演算法的時間複雜度降低到 o n log n 嗎?解法1 動態規劃空間複雜度o n 時間複雜度o n 2...

Leetcode 300 最長上公升子串行

給定乙個無序的整數陣列,找到其中最長上公升子串行的長度。示例 輸入 10,9,2,5,3,7,101,18 輸出 4解釋 最長的上公升子串行是 2,3,7,101 它的長度是4。說明 高階 你能將演算法的時間複雜度降低到 o n log n 嗎?動態規劃 o n 2 的狀態很好定義 dp i 表示以...