题目描述
假设把某股票的价格按照时间先后顺序存储在数组中,请问买卖该股票一次可能获得的最大利润是多少?
示例1:
输入: [7,1,5,3,6,4]
输出: 5
解释: 在第 2 天(股票价格 = 1)的时候买入,在第 5 天(股票价格 = 6)的时候卖出,最大利润 = 6-1 = 5 。
注意利润不能是 7-1 = 6, 因为卖出价格需要大于买入价格。
示例2:
输入: [7,6,4,3,1]
输出: 0
解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
解题思路
因为涉及到最优解因此使用动态规划思想来解答。由于只对股票进行一次的买入和卖出操作,因此只需要分别找到买入和卖出的最佳时机即可,话句话说就是找到数组中的最小值为买入点,最大值为卖出点。
问题的目标分析清楚了, 那么就下来的关键就是明确动态规划的三要素:
- dp[i]状态元素的定义:既然要求的是最大的利润值,那显而易见dp[i]的含义是以当前下标i为结尾的子数组的利润的最大值
- 转移方程:当前i日的利润dp[i]的值为此前一段时间内的利润最大值加上第i日的利润:dp[i] = max(dp[i-1],prices[i]-min(preice[0:i])),其中prices是给定的价值数组。
- 初始状态: 由于dp表代表的是利润,因此dp[0]代表第一天的利润,为0;
可以使用一个变量代替dp 列表
代码实现
import javax.swing.*;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] nums = null;
//键盘输入数组,以空格分隔
nums = sc.nextLine().split(" ");
int[] num = new int[nums.length];
for(int i = 0; i < nums.length; i++){
num[i] = Integer.valueOf(nums[i]);
}
System.out.println(maxProfit(num));
}
public static int maxProfit(int[] prices){
if(prices.length == 0) return 0;
int res = 0, min = prices[0];
for(int i = 1; i < prices.length; i ++){
//动态寻找股票价格最小值
min = Math.min(min, prices[i-1]);
//动态计算利润最大值
res = Math.max(res, prices[i] - min);
}
return res;
}
}