1. Best Time to Buy and Sell Stock
Say you have an array for which the ith element is the price of a given stock on day i.
If you were only permitted to complete at most one transaction (i.e., buy one and sell one share of the stock), design an algorithm to find the maximum profit.
Note that you cannot sell a stock before you buy one.
Example 1:
Input: [7,1,5,3,6,4]
Output: 5
Explanation: Buy on day 2 (price = 1) and sell on day 5 (price = 6), profit = 6-1 = 5.
Not 7-1 = 6, as selling price needs to be larger than buying price.
Example 2:
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.
题意:数组依次代表股票价格,哪天买入,哪天卖出获利最大。
解法:贪心,cur_min 更新最小的买入价格,profit更新最大利润
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
if(n < 2) return 0;
int minPrice = prices[0], profit = 0;
for(int i = 1; i < n; ++i){
minPrice = min(minPrice, prices[i]);
profit = max(profit, prices[i] - minPrice);
}
return profit;
}
};
2. Best Time to Buy and Sell Stock II
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete as many transactions as you like (i.e., buy one and sell one share of the stock multiple times).
Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).
Example 1:
Input: [7,1,5,3,6,4]
Output: 7
Explanation: Buy on day 2 (price = 1) and sell on day 3 (price = 5), profit = 5-1 = 4.
Then buy on day 4 (price = 3) and sell on day 5 (price = 6), profit = 6-3 = 3.
Example 2:
Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
engaging multiple transactions at the same time. You must sell before buying again.
Example 3:
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.
题意:可以多次买入卖出。
解法一:每次交易寻找局部最小值和最大值来买入和卖出。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int profit = 0;
int n = prices.size();
int i = 0;
while(i < n - 1){
int buy, sell;
while(i + 1 < n && prices[i] > prices[i + 1])
++i;
buy = i;
++i;
while(i < n && prices[i] >= prices[i - 1])
//这里不写成i < n - 1的好处是可以避免最后两个数递减的情况会数组越界
++i;
sell = i - 1;//最后一次比较多加了一
profit += (prices[sell] - prices[buy]);
}
return profit;
}
};
解法二:只要后一天比前一天高就交易,这里并不是每次都会真正交易,只是为了利润最大可以这么算,比如[1,2,3,4,5],a[1] - a[0]赚了,而a[2] - a[1]也赚,合起来就相当于a[1] - a[0] + a[2] - a[1] = a[2] - a[0],以此类推。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int profit = 0;
int n = prices.size();
for(int i = 0; i < n - 1; ++i){
if(prices[i] < prices[i + 1])
profit += (prices[i + 1] - prices[i]);
}
return profit;
}
};
3. Best Time to Buy and Sell Stock III
Say you have an array for which the ith element is the price of a given stock on day i.
Design an algorithm to find the maximum profit. You may complete at most two transactions.
Note: You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).
Example 1:
Input: [3,3,5,0,0,3,1,4]
Output: 6
Explanation: Buy on day 4 (price = 0) and sell on day 6 (price = 3), profit = 3-0 = 3.
Then buy on day 7 (price = 1) and sell on day 8 (price = 4), profit = 4-1 = 3.
Example 2:
Input: [1,2,3,4,5]
Output: 4
Explanation: Buy on day 1 (price = 1) and sell on day 5 (price = 5), profit = 5-1 = 4.
Note that you cannot buy on day 1, buy on day 2 and sell them later, as you are
engaging multiple transactions at the same time. You must sell before buying again.
Example 3:
Input: [7,6,4,3,1]
Output: 0
Explanation: In this case, no transaction is done, i.e. max profit = 0.
题意:只允许两次交易。
解法一:相当于在0~i - 1 之间有一次交易,另一次在 i ~ n - 1之间有一次,那么把所有两段区间的利润算出来,取最大的。
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n = prices.size();
if(n < 2) return 0;
vector<int> A(n);
vector<int> B(n);
int profit = 0;
int minPrice = prices[0];
for(int i = 1; i < n; ++i){
minPrice = min(minPrice, prices[i]);
A[i] = max(A[i - 1], prices[i] - minPrice);
}
int maxPrice = prices[n - 1];
for(int i = n - 2; i >= 0; --i){
maxPrice = max(maxPrice, prices[i]);
B[i] = max(B[i + 1], maxPrice - prices[i]);
}
for(int i = 0; i < n; ++i)
profit = max(profit, A[i] + B[i]);
return profit;
}
};
4. Best Time to Buy and Sell Stock with Transaction Fee
Your are given an array of integers prices, for which the i-th element is the price of a given stock on day i; and a non-negative integer fee representing a transaction fee.
You may complete as many transactions as you like, but you need to pay the transaction fee for each transaction. You may not buy more than 1 share of a stock at a time (ie. you must sell the stock share before you buy again.)
Return the maximum profit you can make.
Example 1:
Input: prices = [1, 3, 2, 8, 4, 9], fee = 2
Output: 8
Explanation: The maximum profit can be achieved by:
Buying at prices[0] = 1
Selling at prices[3] = 8
Buying at prices[4] = 4
Selling at prices[5] = 9
The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
Note:
0 < prices.length <= 50000.
0 < prices[i] < 50000.
0 <= fee < 50000.
题意:不限制买入卖出次数,但每次交易有交易费。
解法:sold[i]表示第i天卖掉股票此时的最大利润,hold[i]表示第i天保留手里的股票此时的最大利润。那么我们来分析递推公式,在第i天,如果我们要卖掉手中的股票,那么此时我们的总利润应该是前一天手里有股票的利润(不然没股票卖毛啊),加上此时的卖出价格,减去交易费得到的利润总值,跟前一天卖出的利润相比,取其中较大值,如果前一天卖出的利润较大,那么我们就前一天卖了,不留到今天了。然后来看如果第i天不卖的利润,就是昨天股票卖了的利润然后今天再买入股票,得减去今天的价格,得到的值和昨天股票保留时的利润相比,取其中的较大值,如果昨天保留股票的利润大,那么我们就继续保留到今天,所以递推时可以得到:
sold[i] = max(sold[i - 1], hold[i - 1] + prices[i] - fee);
hold[i] = max(hold[i - 1], sold[i - 1] - prices[i]);
class Solution {
public:
int maxProfit(vector<int>& prices, int fee) {
int n = prices.size();
if(n == 0) return 0;
vector<int> sold(n, 0), hold = sold;
hold[0] = -prices[0];
for(int i = 1; i < n; ++i){
sold[i] = max(sold[i - 1], hold[i - 1] + prices[i] - fee);
hold[i] = max(hold[i - 1], sold[i - 1] - prices[i]);
}
return sold[n - 1];
}
};