給定一個整數陣列,求它的一個最長遞增子序列。
阿新 • • 發佈:2018-12-24
題目描述:如題。
樣例:
輸入 :
5
1 5 2 3 6 9
輸出:
1 2 3 6 9
分析:
本題最好的解法是使用動態規劃,首先要想明白一個問題:如何找到以a[n]作為最後一個元素的最長子列。
要找到以a[n]作為最後一個元素的最長子列,我們需要找出陣列中所有的a[n]之前並且比a[n]小的元素集合,設為S(a[s]), 設在S(a[s])中以元素a[s]為最後一個元素的子列為Ls(a[s]), 選擇Ls(a[s])中最長的一個加上a[n]自身就得到了以a[n]元素為隊尾的最長子列。
要得到最終答案只需要再次遍歷陣列,比較所有以a[k](0 < k <= n)為隊末的佇列長度並選擇最長的一個即可。
Java解答:
import java.util.Arrays; import java.util.List; import java.util.Scanner; import com.google.common.collect.Lists; public class LonggestSon { // 輸出陣列的最長有序子序列,(子序列不要求緊緊相連) // 如 1 4 2 3 6 9最長子序列為:1 2 3 6 9 // 演算法思路為動態規劃,下一步選擇建立在最優的上一步選擇之上。 public static void main(String[] args) { int[] array = new int[] {}; try { array = LonggestSon.getScanArray(); } catch (Exception e) { e.printStackTrace(); } LonggestSon.getMaxLethSon(array); } public static int[] getScanArray() throws Exception { int[] result; Scanner scanner = new Scanner(System.in); int lenth = Integer.parseInt(scanner.nextLine()); result = new int[lenth]; String arryStr = scanner.nextLine(); String[] arrays = arryStr.split(" "); if (arrays.length != lenth) { throw new Exception("length error"); } for (int i = 0; i < lenth; i++) { result[i] = Integer.parseInt(arrays[i]); } return result; } public static int[] getMaxLethSon(int[] a) { int[] marks = new int[a.length]; for (int i = 0; i < a.length; i++) { int currentMaxleth = 0; for (int j = 0; j < i; j++) { if (a[j] < a[i] && marks[j] > currentMaxleth) { currentMaxleth = marks[j]; } } marks[i] = currentMaxleth + 1; } System.out.println("arrays:" + Arrays.toString(a)); System.out.println("marks :" + Arrays.toString(marks)); int maxleth = 0; int maxlethpos = 0; for (int i = 0; i < marks.length; i++) { if (marks[i] > maxleth) { maxleth = marks[i]; maxlethpos = i; } } System.out.println("最長子序列長度 =" + maxleth); List<Integer> son = Lists.newArrayList(); son.add(a[maxlethpos]); int currentleth = maxleth; for (int i = maxlethpos - 1; i >= 0; i--) { if (marks[i] == currentleth - 1) { currentleth--; son.add(a[i]); } } List<Integer> trueSon = Lists.reverse(son); System.out.println("最長子序列為:" + trueSon); return new int[] { 0 }; } }