The maximum dynamic programming algorithm of increasing subsequence problem (Java language)

The largest number of problem solving sequence array

public static void main(String[] args) {

 	int[] arr = {1,5,2,7,4,9,10,11,8,14,13};
	System.out.println(maxLISCount1(arr));
	System.out.println(maxLISCount2(arr));
}

/**
  * 最长递增子序列长度
  * int[] arr = {1,5,2,7,4,9,10,11,8,14,13};
  *
  * 1. 定义数组s[i] 是以arr[i]结尾的最大子序列的个数
  * 2. 分别计算s[i]
  * 3. 找出s[i]的最大值,并且返回
  */
 private static int maxLISCount1(int[] arr){
     //创建一个s数组,并且数值元素值为1
     int[]s = new int[arr.length];
     for (int i = 0; i < s.length; i++) {
         s[i] = 1;
     }

     //计算s[i]的值。 s[i] = s[j]+1。 {存在一个最大的j使得j<i&& arr[j]<arr[i],且s[j]是最大值}
     for (int i = 0; i < arr.length; i++) {
         int item = arr[i];
         //判断是有存在元素j,使得j<i&& arr[j]<arr[i]
         for(int j=i-1;j>=0;j--){
             if(arr[j]<item){
                 if(s[i]<s[j]+1){
                     s[i] = s[j]+1;
                 }
             }
         }
     }

     int count =0;
     for (int i = 0; i < s.length; i++) {
        if(count<s[i]){
            count = s[i];
        }

     }
     return count;
 }

 /**
  * 最长递增子序列长度
  * int[] arr = {1,5,3,7,9,8};
  *
  * 创建一个栈,将元素压栈,如果要压栈的元素小于栈顶元素,则将该元素,替换栈中仅大于它的元素。否则直接压栈。最后返回栈的长度。
  *
  */
 private static int maxLISCount2(int[] arr){
     //用队列模仿栈的思想。
     List<Integer> list = new ArrayList<>();

     for (int i = 0; i < arr.length; i++) {
         if(list.isEmpty()){
             list.add(arr[i]);
         }else {
             if(list.get(list.size()-1)<arr[i]){
                 list.add(arr[i]);
             }else {
                 //定位并替换元素
                 for (int j = list.size()-1; j >= 0; j--) {
                     //替换并删除
                     if(arr[i]<list.get(j)){
                         list.add(j,arr[i]);
                         list.remove(j+1);
                         break;
                     }

                 }
             }
         }
     }
     return list.size();
 }

Problem solving array of maximum increasing subsequence

public static void main(String[] args) {

 	int[] arr = {1,5,2,7,4,9,10,11,8,14,13};
	System.out.println(maxLISListOne(arr2));
    List<List<Integer>> lists = maxLISListAll(arr2);
    for (List<Integer> i:
    lists){
        System.out.println(i);
    }
}


/**
 * 输出一个最长递增子序列
  * int[] arr = {1,5,3,7,9,8};
  *
  * 1. 定义数组s[i] 是以arr[i]结尾的最大子序列的个数
  * 2. 分别计算s[i]
  * 3. 找出s[i]的最大值,并且返回
  *
  */
 private static List<Integer> maxLISListOne(int[] arr){
     //创建一个s数组,并且数值元素值为1
     int[]s = new int[arr.length];
     int[] pre = new int[arr.length];
     for (int i = 0; i < s.length; i++) {
         s[i] = 1;
     }

     for (int i = 0; i < pre.length; i++) {
         pre[i] = -1;
     }

     //计算s[i]的值。 s[i] = s[j]+1。 {存在一个最大的j使得j<i&& arr[j]<arr[i]}
     for (int i = 0; i < arr.length; i++) {
         int item = arr[i];
         //判断是有存在元素j,使得j<i&& arr[j]<arr[i]
         for(int j=i-1;j>=0;j--){
             if(arr[j]<item){
                 if( s[i] < s[j]+1){
                     s[i] = s[j]+1;
                     pre[i] = j;
                 }
             }
         }
     }

     int endIndex =0;
     int count = 0;
     for (int i = 0; i < s.length; i++) {
        if(count<s[i]){
            count = s[i];
            endIndex = i;
        }
     }

     List<Integer> result = new ArrayList<>();

     while (endIndex>=0){
         //遍历输出结果
         result.add(arr[endIndex]);
         endIndex = pre[endIndex];
     }
     Collections.reverse(result);

     return result;

 }


 /**
  * 输出所有最长递增子序列,如果存在多个最长递增子序列
  * int[] arr = {1,5,3,7,9,8};
  *
  * 1. 定义数组s[i] 是以arr[i]结尾的最大子序列的个数
  * 2. 分别计算s[i]
  * 3. 找出s[i]的最大值,并且返回
  *
  */
 private static List<List<Integer>> maxLISListAll(int[] arr){
     //创建一个s数组,并且数值元素值为1
     int[]s = new int[arr.length];
     List<List<Integer>> pres = new ArrayList<>();
     for (int i = 0; i < s.length; i++) {
         s[i] = 1;
     }

     for (int i = 0; i < arr.length; i++) {
         pres.add(new ArrayList<>());
     }

     //计算s[i]的值。 s[i] = s[j]+1。 {存在一个最大的j使得j<i&& arr[j]<arr[i]}
     for (int i = 0; i < arr.length; i++) {
         int item = arr[i];
         //判断是有存在元素j,使得j<i&& arr[j]<arr[i]
         //这里一定要把所有的前驱都找出来
         for(int j=i-1;j>=0;j--){
             if(arr[j]<item){
                 if( s[i] < s[j]+1){
                     s[i] = s[j]+1;
                     pres.get(i).clear();
                     pres.get(i).add(j);
                 }else if(s[i]==s[j]+1){
                     pres.get(i).add(j);
                 }
             }
         }
     }

     List<Integer> endIndex = new ArrayList<>();
     int count = 0;
     for (int i = 0; i < s.length; i++) {
         if(count<s[i]){
             count = s[i];
             endIndex.clear();
             endIndex.add(i);
         }else if(count==s[i]){
             endIndex.add(i);
         }
     }

     //打印前驱数据
     System.out.println(pres);

     List<Integer> record = new ArrayList<>();
     List<List<Integer>> results = new ArrayList<>();
     compose(record,pres,endIndex,arr,results);
     return results;

 }

 /**
  * 根据记录在数组pres中的前驱进行组合打印所有的可能
  * @param record
  * @param pres 
  * @param endIndex
  * @param arr
  * @param results
  */
 private static void compose(List<Integer> record, List<List<Integer>> pres, List<Integer> endIndex,int[]arr,List<List<Integer>>results) {
     if(endIndex.isEmpty()){
         List<Integer> a = new ArrayList<>(record);
         Collections.reverse(a);
         results.add(a);
         return ;
     }
     for (int index :
             endIndex) {
         //加入item arr[endIndex]
         record.add(arr[index]);
         compose(record,pres,pres.get(index),arr,results);
         record.remove(Integer.valueOf(arr[index]));
     }
 }
Published 98 original articles · won praise 6 · views 20000 +

Guess you like

Origin blog.csdn.net/dirksmaller/article/details/104169326