题目
分析
和之前做的一个题目很像,之前那个题目是使用贪心算法,因为那个题目可以无限制购买股票
但是这个题目只要求买入和卖出一次股票
这个题目有两种思路:
- 看看在第i天买入可以赚多少钱(需要在第i天之后找到一个最大值,利润最大)
- 看看第i天卖出可以赚多少钱(需要找到第i天之前的最小值,利润最大)
第一种找最大值,随着i变大,需要去掉前边的数字,从后边找最大值,去掉一个数字,其实很难再重新找到一个最大值,只能再次遍历,
第二种找最小值,随着i变大,需要不断增加数字,增加数字就很容易确定最小值了,只需要看增加的数字和之前的最小值即可
所以,分析可以看出,第二种找最小值更优秀
代码实现
第一种
class Solution {
public int maxProfit(int[] prices) {
int max=0;
int[] result = new int[prices.length];
for(int i = 0; i<prices.length;i++) {
for(int j = i+1;j<prices.length;j++){
if(prices[j]-prices[i]>max) {
max = prices[j]-prices[i];
}
}
}
return max;
}
}
结果第一种因为算法问题,超出时间限制,原因还是我上边分析的,不能快速得到去掉i之后的最大值
第二种
class Solution {
public int maxProfit(int[] prices) {
int max=0;
int priceMin = 100000;
//遍历是看第i天卖出的话,最多挣多少钱
for(int i = 0; i<prices.length;i++) {
//遍历到i时,如果i就是最小值,那i卖出肯定不会赚钱
if(prices[i]<priceMin) {
priceMin = prices[i];
//i不是最小值而且I的时候比i之前的最小值赚钱超过了max说明这个点赚钱多
//这其实是一种动态规划,其中第i天卖出的最大利润,就要看i天之前的最小值,
//而这个值正好使我们一直存起来的,所以直接判断i和之前最小值的大小就可以了
} else if(prices[i]-priceMin > max) {
max = prices[i]-priceMin;
}
}
return max;
}
}
总结
其实很多时候,对于这种数组的处理顺序,我们都是很容易搞反的,例如第一种方式,就不如第二种方式好,所以当我们处理数组的时候,尤其是需要遍历处理数组的时候,当我们觉得正序处理起来很麻烦,应当尽早想到倒序处理,或者我们在处理数组之前,就对比好正序处理和倒序处理,避免闷头前进却走错方向!!!