Java實現求數組最長子序列算法示例
本文實例講述了Java實現求數組最長子序列算法。分享給大家供大家參考,具體如下:
問題:給定一個長度為N的數組,找出一個最長的單調自增子序列(不一定連續(xù),但是順序不能亂) 例如:給定一個長度為8的數組A{1,3,5,2,4,6,7,8},則其最長的單調遞增子序列為{1,2,4,6,7,8},長度為6。
思路1:第一眼看到題目,很多人肯定第一時間想到的是LCS。先給數組排個序形成新數組,然后再把新數組和原數組拿來求LCS,即可得到答案。這種解法很多人能想得到,所以就不再贅述。
思路2:按照思路1的想法,最后求LCS時還是得用到DP,我們干嘛不直接用DP來求解呢。對于數組arr,我們從后往前遍歷數組,分別求出當子序列以arr[i]結尾時的最長子序列,然后取其中的最大值。即可得到整個數組的最長子序列。 那么怎么求以arr[i]結尾時的最長子序列呢,這就轉換成一個DP問題了。要求arr[i]的最長子序列,只需要求出arr[i-1]的最長子序列。即:max{arr[i]}=max{arr[i-1]}+1。
java實現代碼:
public class arrDemo {
public static void main(String[] args) {
// int[] arr = {89, 256, 78, 1, 46, 78, 8};
int[] arr = { 1, 3, 5, 2, 4, 6, 7, 8 };
// int[] arr = {6, 4, 8, 2, 17};
int max = 0;
int maxLen = arr.length;
// 從后往前遍歷數組,分別求出以arr[i]結尾的時候的最長子序列長度
for (int i = arr.length - 1; i > 0; i--) {
int[] newArr = new int[i];
System.arraycopy(arr, 0, newArr, 0, i);
int currentLength = 1 + dp(newArr, arr[i]);
if (currentLength > max)
max = currentLength;
// 最長子序列的長度最長為原始數組的長度,
// 因為不需要我們求最長子序列的元素,所以直接結束循環(huán),減少時間開銷
if (max == maxLen)
break;
}
System.out.println(max);
}
public static int dp(int[] arr, int end) {
// 遞歸結束條件
if (arr.length == 1) {
// 小于end則包含在子序列中,子序列長度+1
if (arr[0] <= end)
return 1;
else
return 0;
}
// 遍歷數組,找到最靠近end的并且<=end的元素位置i
for (int i = arr.length - 1; i >= 0; i--) {
if (arr[i] <= end) {
// 從i處截斷數組,將arr[0]到arr[i-1]組成新數組繼續(xù)遞歸求長度
int[] newArr = new int[i];
System.arraycopy(arr, 0, newArr, 0, i);
// 分別計算包含arr[i]時的最長子序列和不包含arr[i]時的最長子序列,取最大值
int containLen = dp(newArr, arr[i]) + 1;
int notContainLen = dp(newArr, end);
return containLen > notContainLen ? containLen : notContainLen;
}
}
// 如果沒找到比end更小的,返回長度為0
return 0;
}
}
運行結果:
6
我的方法由于中間開辟了多個新數組,可能占用的空間有點多,不過我覺得應該也不是很多- -,具體我也沒統(tǒng)計過。如果有不對的地方還請指正。
更多關于java算法相關內容感興趣的讀者可查看本站專題:《Java數據結構與算法教程》、《Java操作DOM節(jié)點技巧總結》、《Java文件與目錄操作技巧匯總》和《Java緩存操作技巧匯總》
希望本文所述對大家java程序設計有所幫助。
相關文章
Java8中對于LocalDateTime的序列化和反序列化問題
這篇文章主要介紹了Java8中對于LocalDateTime的序列化和反序列化問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-06-06
Java中常用的數據庫連接池_動力節(jié)點Java學院整理
數據庫連接池負責分配、管理和釋放數據庫連接,它允許應用程序重復使用一個現有的數據庫連接,而不是再重新建立一個;釋放空閑時間超過最大空閑時間的數據庫連接來避免因為沒有釋放數據庫連接而引起的數據庫連接遺漏2017-08-08
java實現附件預覽(openoffice+swftools+flexpaper)實例
本篇文章主要介紹了java實現附件預覽(openoffice+swftools+flexpaper)實例,具有一定的參考價值,感興趣的小伙伴們可以參考一下。2016-10-10

