最大递增(减)子序列

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();
     }
 }


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值