class Solution {
public int bestTiming(int[] prices) {
int n=prices.length;
if(n==0)return 0;
int res=0;
int mi=prices[0];
for(int i=0;i<n;i++){
res=Math.max(res,prices[i]-mi);
mi=Math.min(mi,prices[i]);
}
return res;
}
}
public int bestTiming(int[] prices) {
if(prices.length 0) return 0;
int min = prices[0];
int n = prices.length;
int profit = Integer.MIN_VALUE;
int [] dp = new int [n];
dp[0] = 0;
for (int i = 1; i < n; i++) {
min = Math.min(min, prices[i]);//找最低价格
dp[i] = Math.max(dp[i – 1], prices[i] – min);
}
for (int i = 0; i < n; i++) {
profit = Math.max(profit, dp[i]);
}
return profit;
}
共以下 8 个回答
解题思路
– 定义dp[i],表示以(0,i)这个区间内的最大利润,还需要额外定义一个变量min表示最低价格
– dp[i]=Max(dp[i-1],prices[i]-min),并且更新min
– dp[0]=0,min=prices[0]
【题解1】自己的解法,能通过“连续和最大值”悟出可以dp定义的灵活性,已经创造性得把临时变量minValue引入,其实已经很不错了
【题解2】 dp[]优化成1个变量
时间复杂度O(N),空间复杂度O(1)。
一次遍历,O(n)
思路: 本题目只能买卖一次,若可买卖多次 使用状态机
class Solution {
public int bestTiming(int[] prices) {
if(prices.length 0) return 0;
int[][] dp = new int[prices.length][2];
dp[0][1] = -prices[0];
for(int i = 1; i < prices.length; 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[prices.length-1][0];
}
}
思路:只能买卖一次,所以买入是dp[i][1] = Math.max(dp[i-1][1], – prices[i]);
时间:O(n)
空间:O(n)
动态规划
public int bestTiming(int[] prices) {
if(prices.length 0) return 0;
int min = prices[0];
int n = prices.length;
int profit = Integer.MIN_VALUE;
int [] dp = new int [n];
dp[0] = 0;
for (int i = 1; i < n; i++) {
min = Math.min(min, prices[i]);//找最低价格
dp[i] = Math.max(dp[i – 1], prices[i] – min);
}
for (int i = 0; i < n; i++) {
profit = Math.max(profit, dp[i]);
}
return profit;
}