您的位置:首页 > 职场人生

动态规划实践,美团面试题算法实现

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]);

··

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);
}
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: