动态规划实践,美团面试题算法实现
2018-01-18 10:33
239 查看
可能时间复杂度会有很多需要改进的地方。
/* 题目描述
在股市的交易日中,假设最多可进行两次买卖(即买和卖的次数均小于等于2),规则是必须一笔成交后进行另一笔(即买-卖-买-卖的顺序进行)。给出一天中的股票变化序列,请写一个程序计算一天可以获得的最大收益。请采用实践复杂度低的方法实现。
给定价格序列prices及它的长度n,请返回最大收益。保证长度小于等于500。
测试样例:
[10,22,5,75,65,80],6
返回:
87*/
Lis算法的思想实践在这里,应用之算出【0,i】最大递增值,存在一个辅助数组start中
然后将数组反转,算出【0,i】的最小递增负值,,存在一个辅助数组end中
然后遍历size,求出max(start[i] - end[size-1-i]);
··
··
在网上看了别人的算法实现,确实有更简单的方法。因为收益只是一个减法,并没有记录其中间连续的部分。分为K值前和K值后的记录。所有可以记录之前的最小值,再进行动态规划和f[i-1]比较,取最大值。记录之后的最大值,进行动态规划和f【i+1】比较
改进算法
“
“
/* 题目描述
在股市的交易日中,假设最多可进行两次买卖(即买和卖的次数均小于等于2),规则是必须一笔成交后进行另一笔(即买-卖-买-卖的顺序进行)。给出一天中的股票变化序列,请写一个程序计算一天可以获得的最大收益。请采用实践复杂度低的方法实现。
给定价格序列prices及它的长度n,请返回最大收益。保证长度小于等于500。
测试样例:
[10,22,5,75,65,80],6
返回:
87*/
Lis算法的思想实践在这里,应用之算出【0,i】最大递增值,存在一个辅助数组start中
然后将数组反转,算出【0,i】的最小递增负值,,存在一个辅助数组end中
然后遍历size,求出max(start[i] - end[size-1-i]);
··
public class test01 { public static void main(String[] args) { Integer[] a1 = new Integer[]{10, 22, 24,5, 75, 65, 80,89}; int size = a1.length; int[] start =new int[size]; int[] end =new int[size]; List<Integer> reverseList = Arrays.asList(a1); List<Integer> list1 = new ArrayList<>(); list1.addAll(reverseList); Collections.reverse(reverseList); lisStart(list1, start); lisEnd(reverseList, end); int max=0; for(int i = 0; i < size ; i++){ max=Math.max(max,start[i] - end[size-1-i]); } System.out.println(max); } private static void lisEnd(List<Integer> reverseList, int[] end) { int size = reverseList.size(); for (int i = 0 ; i < size ; i++){ end[i] = 0; for (int j = 0 ; j < i ; j++){ if ( reverseList.get(i) < reverseList.get(j) && end [i] > end [j] + reverseList.get(i) - reverseList.get(j)){ end [i] = end [j] + reverseList.get(i) - reverseList.get(j); } } } int min=0; for (int i = 0 ; i < size ; i++){ if (end[i] > min) { end[i] = min; }else{ min = end[i]; } } } private static void lisStart(List<Integer> list1, int[] start) { int size = list1.size(); for (int i = 0 ; i < size ; i++){ start[i] = 0; for (int j = 0 ; j < i ; j++){ if ( list1.get(i) > list1.get(j) && start [i] < start [j] + list1.get(i) - list1.get(j)){ start [i] = start [j] + list1.get(i) - list1.get(j); } } } int max=0; for (int i = 0 ; i < size ; i++){ if (start[i] < max) { start[i] = max; }else{ max = start[i]; } } } }
··
在网上看了别人的算法实现,确实有更简单的方法。因为收益只是一个减法,并没有记录其中间连续的部分。分为K值前和K值后的记录。所有可以记录之前的最小值,再进行动态规划和f[i-1]比较,取最大值。记录之后的最大值,进行动态规划和f【i+1】比较
改进算法
“
public class 美团改进 { public static void main(String[] args) { Integer[] a = new Integer[]{10, 22, 24,5, 75, 65, 80,89}; int size = a.length; int[] prePos=new int[size+1]; int[] postPos=new int[size+1]; int min = a[0]; int max = a[size-1]; prePos[0] = 0; postPos[size] = 0; for (int i = 1 ; i < size; i++){ prePos[i] = Math.max(a[i] - min, prePos[i-1]); min = Math.min(a[i], min); } for (int i = size - 1; i >=0 ; i--){ postPos[i] = Math.max(max - a[i],postPos[i+1] ); max = Math.max(a[i], max); } int maxx=Integer.MIN_VALUE; for (int i = 0; i< size; i++){ maxx = Math.max(max, prePos[i] + postPos[i]); } System.out.println(maxx); } }
“
相关文章推荐
- 背包算法递归实现,递归转动态规划的一般方法java实现
- C++实现算法导论十五章动态规划之钢条分割问题
- 【算法系列】——代码实践动态规划
- 算法学习之路:动态规划-最大公共子序列-java实现
- 流水线调度问题实现(动态规划基础---------问题取自算法导论)
- 算法:C++实现动态规划中的几个典型问题
- 算法实现篇之动态规划-Fibonacci
- 动态规划实现最长公共子序列(LCS)算法
- 动态规划的作业排程算法 Java实现
- 算法基础之python实现动态规划中数字三角形和最长上升子序列问题
- 【算法系列】——代码实践动态规划
- 算法学习之路:动态规划-钢条切割-java实现
- 动态规划之钢条切割问题自底向上发的实现(算法导论第15章)
- 算法原理与实践(动态规划与递归)
- 五个常用算法(一):动态规划
- 算法实验之动态规划
- 美团推荐算法实践
- 夜深人静写算法(2):动态规划
- 关于一道面试题,使用C#实现字符串反转算法
- 算法学习之动态规划(一)