代码改变世界

最长递减子序列

2012-08-12 19:30  coodoing  阅读(2670)  评论(0编辑  收藏  举报

问题描述

求一个数组的最长递减子序列比如{9,4,3,2,5,4,3,2}的最长递减子序列为{9,5,4,3,2}。

问题分析

本问题类似编程之美中的求数组中最长递增子序列问题。可以利用动态规划方法解决。

假设在目标数组array[]的前i个元素中,最长递减子序列的长度为LDS[i]。那么

  LDS[i+1] = max{1,LDS[k]+1},其中array[i+1]<array[k],for any k<=i。

即如果array[i+1]<array[k],那么第i+1个元素可以添加到LDS[k]长的子序列后构成一个更长的递减子序列。与此同时,

array[i+1]可以由自身构造成一个长度为1的子序列。

所以代码清单为:

 for (int i = 0; i < len; i++) {
            LDS[i] = 1;
            for (int k = 0; k < i; k++) {
                // LDS[i+1]=max{1,LDS[k]+1}, array[i+1]<array[k],for any k<=i;
                if (array[i] < array[k] && LDS[k] + 1 > LDS[i]) {
                    LDS[i] = LDS[k] + 1;
                }
            }
        }
在获取到LDS数组后,遍历数组,获取构成最长递减子序列的元素。
print(int[] array, int[] lds, int max, int end) {
        if (max == 0)
            return;
        int i = end;
        while (lds[i] != max)
            i--;
        print(array, lds, max - 1, i - 1);
        System.out.print(array[i] + "");
    } 

实现代码

   1: public class LDSProblem {
   2:     public static void maxSubstrDecrease(int[] array) {
   3:         // 数组array中的前i个元素中,最长递减子序列的长度是LDS[i]
   4:         int len = array.length;
   5:         int[] LDS = new int[len];
   6:         int max = 0;
   7:         for (int i = 0; i < len; i++) {
   8:             LDS[i] = 1;
   9:             for (int k = 0; k < i; k++) {
  10:                 // LDS[i+1]=max{1,LDS[k]+1}, array[i+1]<array[k],for any k<=i;
  11:                 if (array[i] < array[k] && LDS[k] + 1 > LDS[i]) {
  12:                     LDS[i] = LDS[k] + 1;
  13:                 }
  14:             }
  15:         }
  16:         max = maxsub(LDS);
  17:         System.out.println("最长递减子序列的长度为:" + max);
  18:         System.out.println("LDS数组为:");
  19:         print(LDS);
  20:         System.out.print("最长递减子序列为:\n");
  21:         print(array, LDS, max, len - 1);
  22:     }
  23:  
  24:     // max:最长子序列长度
  25:     // end:最长递减子序列中的最后一个元素
  26:     // lds:数组array中的前i个元素中,最长递减子序列的长度数组
  27:     private static void print(int[] array, int[] lds, int max, int end) {
  28:         if (max == 0)
  29:             return;
  30:         int i = end;
  31:         while (lds[i] != max)
  32:             i--;
  33:         print(array, lds, max - 1, i - 1);
  34:         System.out.print(array[i] + " ");
  35:     }
  36:  
  37:     private static void print(int[] array) {
  38:         for (int i = 0; i < array.length; i++) {
  39:             System.out.print(array[i] + "  ");
  40:         }
  41:         System.out.println();
  42:     }
  43:  
  44:     public static int maxsub(int[] LDS) {
  45:         int m = 0;
  46:         for (int i = 0; i < LDS.length; i++) {
  47:             if (LDS[i] > m)
  48:                 m = LDS[i];
  49:         }
  50:         return m;
  51:     }
  52:  
  53:     public static void main(String[] args) {
  54:         int[] array = new int[] { 9, 4, 3, 2, 5, 4, 3, 2 };
  55:         /*        System.out.println("数组为:");
  56:          print(array);*/
  57:         maxSubstrDecrease(array);
  58:     }
  59: }