package number;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
/**
* @author ycsun E-mail:stevesun521@gmail.com
* @version 创建时间:2012-10-3 下午4:35:22 类说明
*/
public class ArraysSeq {
private int[] arr;
public ArraysSeq(int[] arr) {
this.arr = arr;
}
/**
* On2复杂度
*/
public void maxIncreaseSeq() {
int max = 0;
int[] lis = new int[arr.length];
Arrays.fill(lis, 1);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < i; j++) {
if (arr[i] > arr[j] && lis[j] + 1 > lis[i]) {
lis[i] = lis[j] + 1;
max = max < lis[i] ? lis[i] : max;
}
}
}
int pre = Integer.MAX_VALUE;
Stack<Integer> stack = new Stack<Integer>();
for (int i = lis.length - 1, t = max; i >= 0; i--) {
if (t == lis[i] && arr[i] < pre) {
t--;
pre = arr[i];
stack.push(arr[i]);
}
}
while (!stack.isEmpty()) {
System.out.print(stack.pop() + " ");
}
System.out.println();
System.out.println("max increase seq length is :" + max);
}
/**
* On2 DP
*/
public void maxIncreaseSeqDP() {
int max = Integer.MIN_VALUE;
int[] dp = new int[arr.length + 1];
dp[0] = 1;
for (int i = 1; i < arr.length; i++) {
dp[i] = 1;
for (int j = 0; j < i; j++) {
if (arr[i] > arr[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
}
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(dp[i] + " ");
}
System.out.println();
for (int i = 0; i < arr.length; i++) {
max = Math.max(max, dp[i]);
}
System.out.println("DP On2 :" + max);
}
/**
* DP O(nlogn) maxV[i] 记录长度是i的递增序列的最大元素的最小值 有 i<j 时 maxV[i]<maxV[j]
* 反证:如果i<j 有maxV[i]>=maxV[j] ,则有a1,a2.....ai 且有b1,b2....bi....bj ,因为maxV[i]>=maxV[j] ,
* 所以a[i]>b[j] => a[i]>=b[j]>b[i] =>a[i] 不是长度是i的递增子序列的最大元素的最小值,矛盾
* 所以 有 i<j 时 maxV[i]<maxV[j]
*/
public void maxIncreaseSeqOpt() {
int[] maxV = new int[arr.length];
maxV[1] = arr[0];
int nmax = 1;
for (int i = 1; i < arr.length; i++) {
int s = 1, e = nmax;
while (s <= e) {
int mid = (s + e) >> 1;
if (maxV[mid] < arr[i]) {
s = mid + 1;
} else {
e = mid - 1;
}
}
nmax = Math.max(nmax, e + 1);
maxV[e + 1] = arr[i];
}
System.out.println(nmax);
for (int i = 0; i < maxV.length; i++) {
System.out.print(maxV[i] + " ");
}
System.out.println();
}
/**
* DP O(nlogn) minV[i] 记录长度为i的递减序列的最小元素的最大值 有 i>j 时 minV[i]<minV[j]
*/
public void maxDecreaseSeqOPT() {
int[] minV = new int[arr.length];
int nmax = 1;
minV[1] = arr[0];
for (int i = 1; i < arr.length; i++) {
int s = 1, e = nmax;
while (s <= e) {
int mid = (s + e) >> 1;
if (minV[mid] < arr[i]) {
e = mid - 1;
} else {
s = mid + 1;
}
}
nmax = Math.max(nmax, e + 1);
minV[e + 1] = arr[i];
}
for (int i = 0; i < minV.length; i++) {
System.out.print(minV[i] + " ");
}
System.out.println();
System.out.println("max decresase seq is :" + nmax);
}
/**
* DP O(n2)
*/
public void maxDecreaseSeqDP() {
int max = 1;
int[] dis = new int[arr.length];
Arrays.fill(dis, 1);
for (int i = 0; i < arr.length; i++) {
for (int j = 0; j < i; j++) {
if (arr[i] < arr[j]) {
dis[i] = Math.max(dis[i], dis[j] + 1);
}
}
}
for (int i = 0; i < arr.length; i++) {
max = Math.max(max, dis[i]);
System.out.print(dis[i] + " ");
}
System.out.println("\nmax decrease seq is :");
Stack<Integer> stack = new Stack<Integer>();
int prev = Integer.MIN_VALUE;
for (int i = dis.length - 1, t = max; i >= 0; i--) {
if (t >= 1 && t == dis[i] && arr[i] > prev) {
stack.push(arr[i]);
t--;
}
}
while (!stack.isEmpty()) {
System.out.print(stack.pop() + " ");
}
System.out.println();
}
public static void main(String args[]) {
int[] arr = { 2, 3, 4, 5, 2, 3, 4, 9 };
ArraysSeq arraysSeq = new ArraysSeq(arr);
arraysSeq.maxIncreaseSeq();
arraysSeq.maxIncreaseSeqDP();
System.out.println("*******************************");
arraysSeq.maxIncreaseSeqOpt();
System.out.println("-------------------------------");
int[] arr1 = { 9, 4, 3, 2, 5, 4, 3, 2 };
ArraysSeq arraysSeq1 = new ArraysSeq(arr1);
arraysSeq1.maxDecreaseSeqDP();
arraysSeq1.maxDecreaseSeqOPT();
}
}
最大递增(减)子序列
最新推荐文章于 2022-12-17 21:54:16 发布