(1)俄罗斯套娃_最大上升子序列

来源:互联网 发布:淘宝店铺故事 编辑:程序博客网 时间:2024/04/29 22:22

           LIS(Longest Increasing Subsequence)最长上升(不下降)子序列,有两种算法复杂度为O(n*logn)和O(n^2)。在上述算法中,若使用朴素的顺序查找在D1..Dlen查找,由于共有O(n)个元素需要计算,每次计算时的复杂度是O(n),则整个算法的时间复杂度为O(n^2),与原来算法相比没有任何进步。但是由于D的特点(2),在D中查找时,可以使用二分查找高效地完成,则整个算法时间复杂度下降为O(nlogn),有了非常显著的提高。需要注意的是,D在算法结束后记录的并不是一个符合题意的最长上升子序列!算法还可以扩展到整个最长子序列系列问题。

1.算法:

package protest;public class 最大上升子序列_Lis {    public static void main(String[] args) {        String str="3223456189";        System.out.println(lis(str));    }    public static int lis(String str) {        char[] ch = str.toCharArray();        int max;//记录当前对应的最大长度        int ans = 0;//记录总共的最大长度        for (int i = 1; i < ch.length; i++) {            max = 0;//对应该ch[i]开始时,总是要初始化max            for (int j = ans; j >= 0; j--) {                if (ch[i] > ch[j]) {//找到比ch[i]小的                    max = j + 1;//j代表的是ch[j]对应最大上升子序列的长度,加1也就是在该子序列后面再加ch[i]                    ans=ans>max?ans:max;//如果ch[i]对应的长度大于ans,就赋值给ans                    break;                }            }            if( max==ans || ch[i]<ch[max])//max==ans表示当前得到的是最长的子序列,直接存下来就好了。否则得到的不是最长的,就要和之前的比较,存较小的。                ch[max]=ch[i];                        System.out.println(ch);        }        return ans+1;//下标加1才是长度。    }}