最大递增(减)子序列

  1 package number;
  2 
  3 import java.util.Arrays;
  4 import java.util.Iterator;
  5 import java.util.List;
  6 import java.util.Stack;
  7 
  8 /**
  9  * @author ycsun E-mail:stevesun521@gmail.com
 10  * @version 创建时间:2012-10-3 下午4:35:22 类说明
 11  */
 12 public class ArraysSeq {
 13     private int[] arr;
 14 
 15     public ArraysSeq(int[] arr) {
 16         this.arr = arr;
 17     }
 18 
 19     /**
 20      * On2复杂度
 21      */
 22     public void maxIncreaseSeq() {
 23         int max = 0;
 24         int[] lis = new int[arr.length];
 25         Arrays.fill(lis, 1);
 26         for (int i = 0; i < arr.length; i++) {
 27             for (int j = 0; j < i; j++) {
 28                 if (arr[i] > arr[j] && lis[j] + 1 > lis[i]) {
 29                     lis[i] = lis[j] + 1;
 30                     max = max < lis[i] ? lis[i] : max;
 31                 }
 32             }
 33         }
 34         int pre = Integer.MAX_VALUE;
 35         Stack<Integer> stack = new Stack<Integer>();
 36         for (int i = lis.length - 1, t = max; i >= 0; i--) {
 37             if (t == lis[i] && arr[i] < pre) {
 38                 t--;
 39                 pre = arr[i];
 40                 stack.push(arr[i]);
 41             }
 42         }
 43         while (!stack.isEmpty()) {
 44             System.out.print(stack.pop() + " ");
 45         }
 46         System.out.println();
 47         System.out.println("max increase seq length is :" + max);
 48 
 49     }
 50 
 51     /**
 52      * On2 DP
 53      */
 54     public void maxIncreaseSeqDP() {
 55         int max = Integer.MIN_VALUE;
 56         int[] dp = new int[arr.length + 1];
 57         dp[0] = 1;
 58         for (int i = 1; i < arr.length; i++) {
 59             dp[i] = 1;
 60             for (int j = 0; j < i; j++) {
 61                 if (arr[i] > arr[j]) {
 62                     dp[i] = Math.max(dp[i], dp[j] + 1);
 63                 }
 64             }
 65         }
 66         for (int i = 0; i < arr.length; i++) {
 67             System.out.print(dp[i] + " ");
 68         }
 69         System.out.println();
 70         for (int i = 0; i < arr.length; i++) {
 71             max = Math.max(max, dp[i]);
 72         }
 73         System.out.println("DP On2 :" + max);
 74     }
 75 
 76     /**
 77      * DP O(nlogn) maxV[i] 记录长度是i的递增序列的最大元素的最小值 有 i<j 时 maxV[i]<maxV[j]
 78      * 反证:如果i<j 有maxV[i]>=maxV[j] ,则有a1,a2.....ai 且有b1,b2....bi....bj ,因为maxV[i]>=maxV[j] ,
 79      * 所以a[i]>b[j] => a[i]>=b[j]>b[i]  =>a[i] 不是长度是i的递增子序列的最大元素的最小值,矛盾
 80      * 所以 有 i<j 时 maxV[i]<maxV[j]
 81      */
 82     public void maxIncreaseSeqOpt() {
 83         int[] maxV = new int[arr.length];
 84         maxV[1] = arr[0];
 85         int nmax = 1;
 86         for (int i = 1; i < arr.length; i++) {
 87             int s = 1, e = nmax;
 88             while (s <= e) {
 89                 int mid = (s + e) >> 1;
 90                 if (maxV[mid] < arr[i]) {
 91                     s = mid + 1;
 92                 } else {
 93                     e = mid - 1;
 94                 }
 95             }
 96             nmax = Math.max(nmax, e + 1);
 97             maxV[e + 1] = arr[i];
 98         }
 99         System.out.println(nmax);
100         for (int i = 0; i < maxV.length; i++) {
101             System.out.print(maxV[i] + " ");
102         }
103         System.out.println();
104     }
105 
106     /**
107      * DP O(nlogn) minV[i] 记录长度为i的递减序列的最小元素的最大值 有 i>j 时 minV[i]<minV[j]
108      */
109     public void maxDecreaseSeqOPT() {
110         int[] minV = new int[arr.length];
111         int nmax = 1;
112         minV[1] = arr[0];
113         for (int i = 1; i < arr.length; i++) {
114             int s = 1, e = nmax;
115             while (s <= e) {
116                 int mid = (s + e) >> 1;
117                 if (minV[mid] < arr[i]) {
118                     e = mid - 1;
119                 } else {
120                     s = mid + 1;
121                 }
122             }
123             nmax = Math.max(nmax, e + 1);
124             minV[e + 1] = arr[i];
125         }
126         for (int i = 0; i < minV.length; i++) {
127             System.out.print(minV[i] + " ");
128         }
129         System.out.println();
130         System.out.println("max decresase seq is :" + nmax);
131     }
132 
133     /**
134      * DP O(n2)
135      */
136     public void maxDecreaseSeqDP() {
137         int max = 1;
138         int[] dis = new int[arr.length];
139         Arrays.fill(dis, 1);
140         for (int i = 0; i < arr.length; i++) {
141             for (int j = 0; j < i; j++) {
142                 if (arr[i] < arr[j]) {
143                     dis[i] = Math.max(dis[i], dis[j] + 1);
144                 }
145             }
146         }
147         for (int i = 0; i < arr.length; i++) {
148             max = Math.max(max, dis[i]);
149             System.out.print(dis[i] + " ");
150         }
151         System.out.println("\nmax decrease seq is :");
152         Stack<Integer> stack = new Stack<Integer>();
153         int prev = Integer.MIN_VALUE;
154         for (int i = dis.length - 1, t = max; i >= 0; i--) {
155             if (t >= 1 && t == dis[i] && arr[i] > prev) {
156                 stack.push(arr[i]);
157                 t--;
158             }
159         }
160         while (!stack.isEmpty()) {
161             System.out.print(stack.pop() + " ");
162         }
163         System.out.println();
164     }
165 
166     public static void main(String args[]) {
167         int[] arr = { 2, 3, 4, 5, 2, 3, 4, 9 };
168         ArraysSeq arraysSeq = new ArraysSeq(arr);
169         arraysSeq.maxIncreaseSeq();
170         arraysSeq.maxIncreaseSeqDP();
171         System.out.println("*******************************");
172         arraysSeq.maxIncreaseSeqOpt();
173         System.out.println("-------------------------------");
174         int[] arr1 = { 9, 4, 3, 2, 5, 4, 3, 2 };
175         ArraysSeq arraysSeq1 = new ArraysSeq(arr1);
176         arraysSeq1.maxDecreaseSeqDP();
177         arraysSeq1.maxDecreaseSeqOPT();
178     }
179 }
原文地址:https://www.cnblogs.com/waka401/p/2711430.html