给定一个数组,它的第 i 个元素是一支给定股票第 i 天的价格。
如果你最多只允许完成一笔交易(即买入和卖出一支股票),设计一个算法来计算你所能获取的最大利润。
注意你不能在买入股票前卖出股票。
示例 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。
1.最简单的方法,暴力二重循环
class Solution {
public int maxProfit(int[] prices) {
int len= prices.length;
int max=0;
//二重循环
for(int i=0;i<len;i++){
for(int j=i+1 ;j<len;j++){
int temp=prices[j]-prices[i];
if(temp>max){
max=temp;
}
}
}
return max;
}
2.动态规划
动态规划方程是本题的重点
定义dp[i][j],i代表第几天,j代表那天有无持股
dp[][] 代表当天有无持股的 收益
j的取值为 0,1 0代表未持股
则 dp[i][0] 的情况有两种 :第一 :i-1天时未持股 则 dp[i][0]=dp[i-1][0]; 第二 : i-1 天时持股 说明在第i天卖出
dp[i][0]=dp[i-1][1]+prices[i];
接着分析dp[i][1] 的情况 :1. 有可能前一天就已经持股 所以 dp[i][1]=dp[i-1][1];
2.有可能昨天未持股 dp[i][1]=- prices[i];
class Solution {
public int maxProfit(int[] prices) {
int len =prices.length;
if(len==0){
return 0;
}
if(len==1){
return 0;
}
//dp[][] 代表某天不同状态的收益 ,所以在状态转移中取最大即可
int [][] dp= new int [len][2];
//初始化
dp[0][0]=0;
dp[0][1]=-prices[0];
//输出结果 一定是未持股状态 dp【i】【0】
for(int i=1;i<len;i++){
//状态转移
dp[i][0]=Math.max(dp[i-1][0],dp[i-1][1]+prices[i]);
dp[i][1]=Math.max(dp[i-1][1],- prices[i]);
}
return dp[len-1][0];
}
}