码迷,mamicode.com
首页 > 其他好文 > 详细

longestIncreasingSequence最长上升子序列问题

时间:2016-07-25 12:57:10      阅读:178      评论:0      收藏:0      [点我收藏+]

标签:

  1 package dp;
  2 
  3 /**
  4  * 最长上升子序列问题
  5  */
  6 public class LongestIncreasingSubsequence
  7 {
  8     /**
  9      * 原始dp
 10      * @param arr
 11      * @return
 12      */
 13     public static int maxLength(int[] arr)
 14     {
 15         int[] len = new int[arr.length] ; //以i为结尾的最长上升子序列
 16         int[] mark = new int[arr.length] ;//标记以i为结尾的最长上升子序列的上一个节点所在的上上子序列位置
 17         len[0] = 1 ;
 18         mark[0] = -1 ;
 19 
 20         int maxPos = 0 ;
 21         for(int i=1 ; i<len.length ; i++)
 22         {
 23             len[i] = 1 ;
 24             mark[i] = -1 ;
 25             for(int j=i-1 ; j>=0 ; j--)
 26             {
 27                 if(arr[j] < arr[i] && (len[j]+1) > len[i])
 28                 {
 29                     len[i] = len[j]+1 ;
 30                     mark[i] = j ;
 31                 }
 32 
 33             }
 34             if(len[maxPos] < len[i])
 35                 maxPos = i ;
 36         }
 37 
 38 
 39         int maxP = maxPos ;
 40         while (maxP != -1)
 41         {
 42             System.out.println(arr[maxP]);
 43             maxP = mark[maxP] ;
 44         }
 45         return len[maxPos] ;
 46     }
 47 
 48     /**
 49      * 使用二分加速的dp
 50      * @param arr
 51      * @return
 52      */
 53     public static int maxLength2(int[] arr)
 54     {
 55         int[] len = new int[arr.length] ; //以i为结尾的最长上升子序列
 56         int[] mark = new int[arr.length] ;//标记以i为结尾的最长上升子序列的上一个节点所在的上上子序列位置
 57         int[] m = new int[arr.length+1] ;//标记长度为x的子序列的最小值在arr中的位置
 58 
 59         int mLength = 1 ;
 60         len[0] = 1 ;
 61         mark[0] = -1 ;
 62         m[1] = 0 ;
 63 
 64         int maxPos = 0 ;
 65         for(int i=1 ; i<len.length ; i++)
 66         {
 67             len[i] = 1 ;
 68             mark[i] = -1 ;
 69 
 70             int pos = binarySearch(arr , m , mLength , arr[i]) ;
 71             if(pos != -1)
 72             {
 73                 len[i] = len[pos]+1 ;
 74                 mark[i] = pos ;
 75             }
 76 
 77             if(mLength < len[i])
 78             {
 79                 m[len[i]] = i ;
 80                 mLength++ ;
 81             }
 82             else if(arr[m[len[i]]] > arr[i])
 83             {
 84                 m[len[i]] = i ;
 85             }
 86 
 87             if(len[maxPos] < len[i])
 88                 maxPos = i ;
 89         }
 90 
 91 
 92         int maxP = maxPos ;
 93         while (maxP != -1)
 94         {
 95             System.out.println(arr[maxP]);
 96             maxP = mark[maxP] ;
 97         }
 98         return len[maxPos] ;
 99     }
100 
101     /**
102      * 寻找arr中比k小的最大数
103      * @param n 表示m的长度
104      * @param m 表示标记长度为x的子序列的最小值的位置的数组
105      * @return 该元素在arr中的位置(为标记函数而服务的)
106      */
107     private static int binarySearch(int[] arr , int[] m , int n , int k)
108     {
109         int lo = 1 ;
110         int hi = n ;
111 
112         while (lo < hi)
113         {
114             int mid = lo + (hi-lo)/2 ;
115             if(arr[m[mid]] > k)
116                 hi = mid-1 ;
117             else if(arr[m[mid]] < k)
118                 lo = mid+1 ;
119             else
120             {
121                 if(mid == 1)
122                     return -1 ;
123                 else
124                     return m[mid-1] ;
125             }
126         }
127 
128         if(lo == hi)
129         {
130             if(arr[m[lo]] > k)
131                 return m[lo-1] ;
132             else
133                 return m[lo] ;
134         }
135         else if(lo == n+1)
136                 return m[hi] ;
137         return -1 ;
138     }
139 
140     public static void main(String[] args) {
141         int[] arr = new int[]{
142                 1,4,8,3,4,5
143         //    3,5,1,7,5,9,3,5
144         } ;
145 //                1, 7, 3, 5, 9, 4, 1
146 
147         System.out.println(maxLength2(arr));
148     }
149 }

//http://blog.csdn.net/code_pang/article/details/8757380

//http://blog.csdn.net/chenwenshi/article/details/6027086

longestIncreasingSequence最长上升子序列问题

标签:

原文地址:http://www.cnblogs.com/iamzhoug37/p/5702983.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!