返回数组中最长递增字符串

返回数组中最长递增字符串

蚂蚁金服笔试题

思路:把问题化简为子问题,求整个整个数组的最长子序列,我可以先求前面少一个数的递增子序列,
不断递减累加,反过来想就是动态规划,先从arr最左边开始也就是从arr[0]开始当计算arr[1]时只需找到
它前面比他小的递增子序列最大的那一个就可以了,这就是关系状态方程:dp[i]=max{dp[j]+1(0<=j<i,arr[j]<arr[i])}
dp[i]表示在必须以arr[i]这个数结尾的情况下,arr[0....i]中最大递增子序列长度
代码:

package com.ch.evaluation.TestJava;

/**
 * @Auther: 011336
 * @Date: 2019/4/9 14:42
 * 返回数组中最长递增字符串
 */
public class SearchMaxAsc {
    public static void main(String[] args) {
        int[] arry = new int[]{5,6,7,1,2,3,4,};
        //解法一  这个方法只能返回子序列的长度,不能返回子序列
        int num1 = search_max_asc1(arry);
        System.out.println("最大长度 =" + num1);
        //解法一.一  可以返回子序列
        String str = search_max_asc1_1(arry);
        System.out.println("最长子序列 =" + str);
        //解法二 有问题我没改
        int num2 = search_max_asc2(arry);
        System.out.println("最大长度 =" + num2);
    }

    private static int search_max_asc1(int[] arry) {
        int[] lis = new int[arry.length];
        for (int i = 0; i < arry.length; i++) {
            lis[i] = 1;
            for (int j = 0; j < i; j++) {
                if (arry[i] >= arry[j] && lis[j] + 1 > lis[i]) {
                    lis[i] = lis[j] + 1;
                }
            }
        }
        return max(lis);
    }

    private static String search_max_asc1_1(int[] arry) {
        int[] lis = new int[arry.length];
        String[] str = new String[arry.length];
        for (int i = 0; i < arry.length; i++) {
            str[i] = arry[i] + "";
            lis[i] = 1;
            for (int j = 0; j < i; j++) {
                if (arry[i] >= arry[j] && lis[j] + 1 > lis[i]) {
                    lis[i] = lis[j] + 1;
                    str[i] = str[j];
                    str[i] += "," + arry[i];
                }
            }
        }
        int n = max_num(lis);
        return str[n];
    }

    private static int search_max_asc2(int[] arry) {
        //记录数组中的递增序列信息
        int[] MaxV = new int[arry.length];

        MaxV[1] = arry[0];                //数组中的第一值,边界值
        MaxV[0] = min(arry) - 1;            //数组中最小值,边界值
        int[] LIs = new int[arry.length];

        //初始化最长递增序列的信息
        for (int i : LIs) {
            i = 1;
        }

        int nMaxLIs = 1;              //数组最长递增子序列的长度

        for (int i = 1; i < arry.length; i++) {
            //遍历历史最长递增序列信息
            int j;
            for (j = nMaxLIs; j >= 0; j--) {
                if (arry[i] > MaxV[j]) {
                    LIs[i] = j + 1;
                    break;
                }
            }

            //如果当前最长序列大于最长递增序列长度,更新最长信息
            if (LIs[i] > nMaxLIs) {
                nMaxLIs = LIs[i];
                MaxV[LIs[i]] = arry[i];
            }else if(MaxV[j] <arry[i] &&arry[i]<MaxV[j+1]){
                MaxV[j+1] = arry[i];
            }
        }
        return nMaxLIs;
    }

    private static int max(int[] lis) {
        int max = lis[0];
        for (int i = 1; i < lis.length; i++) {
            if (lis[i] > max) {
                max = lis[i];
            }
        }
        return max;
    }

    private static int max_num(int[] lis) {
        int max = lis[0];
        int num = 0;
        for (int i = 1; i < lis.length; i++) {
            if (lis[i] > max) {
                max = lis[i];
                num = i;
            }
        }
        return num;
    }

    private static int min(int[] lis) {
        int min = lis[0];
        for (int i = 1; i < lis.length; i++) {
            if (lis[i] < min) {
                min = lis[i];
            }
        }
        return min;
    }
}

 

posted @ 2019-05-07 10:44  隔壁w王叔叔  阅读(362)  评论(0编辑  收藏  举报