思路:实质上是找数组中后一个元素与之前元素的最大差值
暴力法:对于每组 i 和 j(其中 j > i)我们需要找出 max(prices[j] - prices[i])
class Solution {
public int maxProfit(int[] prices) {
int ans = 0;
int n = prices.length;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
int profit = prices[j] - prices[i];
if (profit > ans){
ans = profit;
}
}
}
return ans;
}
}
思路2:模拟炒股,我们希望在股价最低时买入,最高时卖出。
维护2个变量:截至当前历史最低价,截止当前最大利差
class Solution {
public int maxProfit(int[] prices) {
// 维护2个变量:截至当前历史最低价,截止当前最大利差
int minprice = Integer.MAX_VALUE;
int maxprofit = 0;
for (int i = 0; i < prices.length; i++) {
minprice = Math.min(minprice, prices[i]);
maxprofit = Math.max(maxprofit, prices[i] - minprice);
}
return maxprofit;
}
}
动态规划,dp[i]表示截止到第 i 天的利润,dp[i]=max(dp[i−1],prices[i]−minprice)
class Solution {
public int maxProfit(int[] prices) {
if (prices.length == 0) return 0;
int minprice = prices[0];
int n = prices.length;
int[] dp = new int[n];
for (int i = 1; i < n; i++) {
minprice = Math.min(minprice, prices[i]);
dp[i] = Math.max(dp[i - 1], prices[i] - minprice);
}
return dp[n - 1];
}
}
双指针:使用两根指针 date_buy、date_sell 分别标记买入和卖出时间,当前操作带来的利润 cur
class Solution {
public int maxProfit(int[] prices) {
if (prices.length <= 1) return 0;
int date_buy = 0, date_sell = 1;
int profit = prices[date_sell] - prices[date_buy];
for (int i = 1; i < prices.length; i++) {
if (prices[date_buy] > prices[i]){ // 低买
date_buy = i; // 更新购买时间
date_sell = date_buy + 1; //卖出时间最早是买入时间的后1天
//高卖
}else if (date_buy < date_sell && prices[date_sell] >= prices[date_buy]){
date_sell = i;
int cur = prices[date_sell] - prices[date_buy];
profit = Math.max(profit, cur);
}
}
return profit > 0 ? profit : 0;
}
}