蚂蚁金服笔试题
思路:把问题化简为子问题,求整个整个数组的最长子序列,我可以先求前面少一个数的递增子序列,
不断递减累加,反过来想就是动态规划,先从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; } }
原文:https://www.cnblogs.com/UncleWang001/p/10824012.html