動態規劃 最長遞增子串行問題 LIS

2022-02-25 04:29:13 字數 2237 閱讀 3095

題目:

輸出最長遞增子串行的長度,如輸入 4 2 3 1 5 6,輸出 4 (因為 2 3 5 6組成了最長遞增子串行)。

暴力破解法:這種方法很簡單,兩層for迴圈搞定,時間複雜度是o(n2)。

動態規劃:之前我們使用動態規劃去解決一般是建立一維陣列或者二維陣列來構建出dp表,利用之前的歷史上dp表中的值進行相關的處理求解出這個過程中的幾個最大值,最小值,然後相加減來得出dp表的當前元素的值,所以我們會想,先建立乙個一維陣列,因為陣列中選擇的元素的範圍在進行變化,所以dp表表示的值為擷取到當前範圍內最長的遞增子串行是多少,但是在填表的過程中發現這種一般方法是不行的。但是這作為一道經典的題目,思路本身是很難的,有人想出來了它的dp解法,我們可以通過借鑑它的思路來幫助我們擴充套件理解dp演算法。

那麼它的思路是:d

p[i]表示的意思是必須包含以dp[i]結尾的最長遞增子串行,那麼它的值就是以dp[i]結尾的最長遞增子串行長度。依次去掃瞄dp[i]這個字元之前的字元,假如發現當前字元大於之前的字元那麼比較當前的最長子序列的長度與當前dp[i] + 1的值的大小來更新當前最長遞增子串行的長度,當掃瞄完當前字元i之前的字元那麼這個時候說明找到了以當前字元結尾的最長遞增子串行的長度,把這個值賦值給dp[i]。

需要注意的是最後還需要掃瞄一下dp陣列,看一下哪乙個dp[i]最大,因為我們不知道以哪個字元結尾的字串行為最長的遞增子串行,所以需要掃瞄一下,最後找到dp[i]的最大值返回,這是與之前的dp陣列不同的乙個點,以前是返回dp陣列的最後乙個元素就可以了,因為最後乙個元素就是我們需要求解的最優解。這個解法時間複雜度也是o(n2)。

那解法三的思路呢:dp[i]表示的是長度為i的最長遞增子串行的末尾的那個數。先初始化dp[0]為陣列中第乙個元素的值,即dp[0]  =  4,定義乙個指標p用來記錄當前遞增子串行的位置,從陣列的第二個元素開始比較當前arr[i]與當前指標指向的dp陣列的位置的值的大小,假如arr[i] > dp[p]那麼說明當前的字元可以構成更長的遞增子串行那麼我們應該更新dp陣列,指標往下移動,然後把當前的arr[i]的值賦值給dp[++p],假如arr[i] < dp[p]說明當前字元不能夠構成更長的遞增子串行,此時需要進行元素的替換,為什麼進行替換呢?因為當前更小的元素更有利於最長遞增子串行的貢獻,所以掃瞄dp陣列指向位置以及之前的位置假如arr[i] 大於dp[p]那麼我們將其dp[p] 替換為arr[i]

最後返回的是指標p指向的位置,注意返回最長遞增子串行的長度是p指向的下標,這也是與之前動態規劃的一般解法不同的點。更進一步的優化就是這種解法在掃瞄dp陣列的過程中可以通過二分查詢來降低時間複雜度,整體從o(n2)降低到o(nlgn)。

**:

package chapter_08_貪心策略與動態規劃;

public class 最長遞增子串行 ;

public static void main(string args)

// 暴力破解法

private static int f(int arr)

}// if (cnt>maxcnt)

maxcnt = math.max(maxcnt, cnt);

} return maxcnt; }

static int dp = new int[arr.length];

// 解法二

private static int dp(int arr)

}dp[i] = cnt;

} int ans = -1;

for (int i = 0; i < dp.length; i++)

return ans;

} // 解法三

/* 在優化之後,可以達到o(nlgn) */

private static int dp1(int arr) else

//}// 二分查詢,比上面掃瞄dp陣列耗時少

int indexoffirstbigger = indexoffirstbigger(dp, arr[i], 0, p);

if (indexoffirstbigger != -1)

dp[indexoffirstbigger] = arr[i];

}} return p;

} /**

* 在遞增陣列中,從左查詢第乙個比v大的元素的下標

*/public static int indexoffirstbigger(int dp, int v, int l, int r) else

if (l == r && dp[l] > v)

return l;

} return -1;

}}

最長遞增子串行問題 動態規劃

假設 字串 l長度為n中定義的遞增子串行是這樣乙個子串行lin k1 ak2 a km 其中k12 m 且ak1 k2 km 求最大的m值。0 f i 表示 以i結束的最大子串行 長度,c i 表示第i個字元,j 如下 created by wuss on 2017 8 29.f i 表示 以i結束...

動態規劃 最長遞增子串行

給出序列 1 2 3 4 2 5 3 4 a 1 1,a 2 2,a 7 3,a 8 4 求其最長的遞增子串行,以上最長遞增子串行為 1 2 3 4 5 問題細分 初始化條件f 1 1,序列只有1個長度即為1 f 2 a 2 與下標小於2的比較,即a 1 比較,a 2 a 1 因此更新f 2 f 1...

動態規劃 最長遞增子串行

給定乙個無序的整數陣列,找到其中最長上公升子串行的長度 例項 輸入 10,9,2,5,3,7,101,18 輸出 4 解釋 最長的上公升子串行為 2,3,7,101 長度為4說明 可能會有多種最長上公升子串行的和,只需要輸出對應長度即可 演算法的時間複雜度應為o n2 首先,dp陣列的定義如下 dp...