1.题目
2.思路
看见这个,首先一想可不可以暴力搜索,O(n * n),一看数据集10^5,大概率过不了,就没写.后来发现能过....
方法一--暴力--O(n * n)
public class Solution {
public int maxProfit(int[] prices) {
int maxprofit = 0;
for (int i = 0; i < prices.length - 1; i++) {
for (int j = i + 1; j < prices.length; j++) {
int profit = prices[j] - prices[i];
if (profit > maxprofit) {
maxprofit = profit;
}
}
}
return maxprofit;
}
}
方法二--贪心-O(n)
进一步思考:这个时间复杂度多半是O(n),那么自然会想到贪心或者一个维度的动态规划.
对于贪心而言的话,需要考虑每一步都是最佳选择,那么问题来了,假如现在是第i天,怎么才可以让今天卖的利润最大???
显示可以得到让今天的price[i] - minPrice就可以了,只需要一直维护前面i天的最小的price就可以了.最后只需要把每一天卖的利润求一个最大值就是答案了.
class Solution {
public int maxProfit(int[] prices) {
// 贪心
int n = prices.length;
if(n == 0) return 0;
int minPrice = prices[0];
int ans = 0;
for(int i = 0 ; i < n; i++){
ans = Math.max(ans, prices[i] - minPrice);
minPrice = Math.min(prices[i], minPrice);
}
return ans;
}
}
方法三-动态规划-O(n)
能用贪心思想解决的题目一般都可以用动态规划, 其实这里用动态规划有点大材小用了..
动态规划三部曲:
1.dp[i]定义:前i天获取到的最大利润.(一般情况下,题目问啥,dp[i]就定义成什么)
2.初始化:dp[0] = 0.
3.最关键的:状态转移函数:dp[i] = Math.max(dp[i -1], price[i] - minPrice);
class Solution {
public int maxProfit(int[] prices) {
// 贪心
// int n = prices.length;
// if(n == 0) return 0;
// int minPrice = prices[0];
// int ans = 0;
// for(int i = 0 ; i < n; i++){
// ans = Math.max(ans, prices[i] - minPrice);
// minPrice = Math.min(prices[i], minPrice);
// }
// return ans;
// 2.动态规划
// dp[i]:第i天卖出去的最大收益
int ans = 0 ;
int n = prices.length;
if(n < 2)return 0;
// 定义dp
int[]dp = new int[n + 1];
// 初始化
// 状态转移函数
int minPrice = prices[0];
for(int i = 1 ; i < n + 1; i++){
dp[i] = Math.max(prices[i - 1] - minPrice, dp[i - 1]);
minPrice = Math.min(prices[i - 1], minPrice);
}
return dp[n];
}
}
3.结果