贪心算法
Posted 浮云神码
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了贪心算法相关的知识,希望对你有一定的参考价值。
今天分享两道关于买卖股票的最佳时机的题目,非常好的应用了贪心算法,一旦可以获利,立刻就将股票卖出。但是仍然假设以当前卖出的价格持有这支股票,如果第二天股票价格更高,则将这部分收益仍然计算在内。
/**
* https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii
* 122. 买卖股票的最佳时机 II
* 难度 简单
* 给定一个数组 prices ,其中prices[i] 是一支给定股票第 i 天的价格。
* 设计一个算法来计算你所能获取的最大利润。你可以尽可能地完成更多的交易(多次买卖一支股票)。
* 注意:你不能同时参与多笔交易(你必须在再次购买前出售掉之前的股票)。
*
* 示例 1:
*
* 输入: prices = [7,1,5,3,6,4]
* 输出: 7
* 解释: 在第 2 天(股票价格 = 1)的时候买入,在第 3 天
* (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
* 随后,在第 4 天(股票价格 = 3)的时候买入,在第 5 天
* (股票价格 = 6)的时候卖出, 这笔交易所能获得利润 = 6-3 = 3 。
* 示例 2:
*
* 输入: prices = [1,2,3,4,5]
* 输出: 4
* 解释: 在第 1 天(股票价格 = 1)的时候买入,在第 5 天
* (股票价格 = 5)的时候卖出, 这笔交易所能获得利润 = 5-1 = 4 。
* 注意你不能在第 1 天和第 2 天接连购买股票,之后再将它们卖出。
* 因为这样属于同时参与了多笔交易,你必须在再次购买前出售掉之前的股票。
*
* 示例3:
* 输入: prices = [7,6,4,3,1]
* 输出: 0
* 解释: 在这种情况下, 没有交易完成, 所以最大利润为 0。
*
* 提示:
*
* 1 <= prices.length <= 3 * 104
* 0 <= prices[i] <= 104
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-ii
*/
public class BestTimeToBuyAndSellStockII {
public int maxProfit(int[] prices) {
int buy = prices[0];
int sum = 0;
for (int i = 1; i < prices.length; i++) {
// 不断更新买入的最低价格
if (prices[i] < buy) {
buy = prices[i];
} else if (prices[i] > buy) {
// 一旦价格高于了买入价格, 就将股票卖出, 体现了贪心的思想
sum += prices[i] - buy;
/**
* 这里将买入价格更新为了本次的卖出价格, 是因为接下来会有两种情况产生
* 1. 第二天的价格高于今天的价格, 说明我们没有把股票在最高点出售,
* 少赚取了prices[i + 1] - prices[i] 的收益, 将buy设置为price[i]
* 刚好将这部分收益计算进来
* 2. 若第二天价格低于今天的价格, 则将买入价格更新为prices[i + 1],
* 没有收益, 重新开始计算买入的最低价格
*/
buy = prices[i];
}
}
return sum;
}
}
/**
* https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee
* 714. 买卖股票的最佳时机含手续费
* 难度 中等
* 给定一个整数数组prices,其中第i个元素代表了第i天的股票价格 ;
* 整数fee 代表了交易股票的手续费用。
*
* 你可以无限次地完成交易,但是你每笔交易都需要付手续费。
* 如果你已经购买了一个股票,在卖出它之前你就不能再继续购买股票了。
* 返回获得利润的最大值。
*
* 注意:这里的一笔交易指买入持有并卖出股票的整个过程,每笔交易你只需要为支付一次手续费。
*
* 示例 1:
* 输入:prices = [1, 3, 2, 8, 4, 9], fee = 2
* 输出:8
* 解释:能够达到的最大利润:
* 在此处买入prices[0] = 1
* 在此处卖出 prices[3] = 8
* 在此处买入 prices[4] = 4
* 在此处卖出 prices[5] = 9
* 总利润:((8 - 1) - 2) + ((9 - 4) - 2) = 8
*
* 示例 2:
* 输入:prices = [1,3,7,5,10,3], fee = 3
* 输出:6
*
* 提示:
*
* 1 <= prices.length <= 5 * 104
* 1 <= prices[i] < 5 * 104
* 0 <= fee < 5 * 104
*
* 来源:力扣(LeetCode)
* 链接:https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock-with-transaction-fee
*/
public class BestTimeToBuyAndSellStockWithTransactionFee {
public int maxProfit(int[] prices, int fee) {
// 将费用计算在买股票的时的价格中
// 这样卖股票就不需要缴费了
int buy = prices[0] + fee;
int sum = 0;
for (int i = 1; i < prices.length; i++) {
// 不断更新买入的最低价格
if (prices[i] + fee < buy) {
buy = prices[i] + fee;
} else if (prices[i] > buy) {
// 只要价格高于买入成本, 就卖出股票 体现了贪心的思想
sum += prices[i] - buy;
/**
* 这时buy要更新成什么呢?答案是卖出的价格
* 1. 若第二天的价格比今天的价格高, 今天卖出的话就相当于没有达到最大收益
* 所以假定我们仍然持有这只股票, 如果第二天的价格高于今天
* 那么我们仍然得到了prices[i + 1] - prices[i] 的收益
* 2. 若第二天的价格 + 手续费 比今天的价格低,
* 则将买入价格更新为prices[i + 1] + fee
* 重新计算买入的最低价格
*/
buy = prices[i];
}
}
return sum;
}
}
以上是关于贪心算法的主要内容,如果未能解决你的问题,请参考以下文章