您的位置:首页 > 其它

最长非上升子序列

2012-06-04 11:38 211 查看

问题描述:

给定一个序列:X1 X2 X3 X4 X5 X6......Xn,试图找到一个最长的子序列,Xi1 Xi2 Xin,使得i1 < i2 < i3 ...而且Xi1 < Xi2 < Xi3......。

举个例子:48 65 34 29 64 38 89

有一种非常简单的做法,能够非常简单的计算出所要序列的长度,但是无法给出序列。过程如下

48

65

65 34

65 34 29

65 64 29

65 64 38

89 64 38

因此最长非上升子序列长度为3,代码如下:

Java

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class SubSeqDesc {

public static void main(String[] args) {

Scanner sin = new Scanner(System.in);
List<Integer> maxList = new ArrayList<Integer>(32);

int ele = 0;
if ((ele = sin.nextInt()) != -1) {
maxList.add(ele);
while ((ele = sin.nextInt()) != -1) {
if (maxList.get(maxList.size() - 1) >= ele) {
maxList.add(ele);
} else {
int i = 0;
while (maxList.get(i) >= ele)
i++;
maxList.set(i, ele);
}
}
System.out.println("the longest subsequence' length is " + maxList.size());
} else {
System.out.println("no sequence...");
}
}

}


另外有一种动态规划的方法。记opt[i](i = 0...len)表示以array[i]为尾的满足条件的序列,那么最终所要求的序列必定在opt[i]中的最大值,也就是序列最大长度。代码如下:

Java

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class SubSeqDesc2 {

public static void main(String[] args) {

Scanner sin = new Scanner(System.in);
List<Integer> maxList = new ArrayList<Integer>(32);

int ele = 0;
while ((ele = sin.nextInt()) != -1) {
maxList.add(ele);
}
int len = maxList.size();
if (len == 0) {
System.out.println("no sequence...");
} else {
Integer[] seq = new Integer[len];
maxList.toArray(seq);
int[] opt = new int[len];
opt[0] = 1;
for(int i = 1; i < len; i++){
opt[i] = 1;
for(int j = 0; j < i; j++){
if(seq[j] >= seq[i] && opt[j] + 1 > opt[i]){
opt[i] = opt[j] + 1;
}
}
}
int result = opt[0];
for(int i = 1; i < len; i++){
if(result < opt[i]){
result = opt[i];
}
}
System.out.println("the longest subseq is " + result);
}
}
}

根据第二个做法,可以通过加入新的前向数组来输出一个最长的子序列:

Java

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class SubSeqDesc3 {

public static void main(String[] args) {

Scanner sin = new Scanner(System.in);
List<Integer> maxList = new ArrayList<Integer>(32);

int ele = 0;
while ((ele = sin.nextInt()) != -1) {
maxList.add(ele);
}
int len = maxList.size();
if (len == 0) {
System.out.println("no sequence...");
} else {
Integer[] seq = new Integer[len];
int[] previous = new int[len];

maxList.toArray(seq);
int[] opt = new int[len];
opt[0] = 1;
previous[0] = -1;

for(int i = 1; i < len; i++){
opt[i] = 1;
previous[i] = -1;
for(int j = 0; j < i; j++){
if(seq[j] >= seq[i] && opt[j] + 1 > opt[i]){
opt[i] = opt[j] + 1;
previous[i] = j;
}
}
}
int result = 0;
for(int i = 1; i < len; i++){
if(result < opt[i]){
result = i;
}
}
System.out.println("length:" + opt[result]);
System.out.print("subsequence:");

LinkedList<Integer> stack = new LinkedList<Integer>();
do{
stack.push(result);
result = previous[result];
}while(result != -1);

while(!stack.isEmpty()){
System.out.print(seq[stack.pop()] + " ");
}
System.out.println();
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  integer string class