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 (ie, buy one and sell one share of the stock), design an algorithm to find the maximum profit.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
// 解法一:
// 思路就是将股价变化的数组转换成股价增长的数组,
// 将问题转换成求和最大的子序列的问题
// 在算法导论里,还有一种分治的解决办法,比较麻烦
class Solution {
public:
/*
* @param prices: Given an integer array
* @return: Maximum profit
*/
int maxProfit(vector<int> &prices) {
vector<int> increment;
for (int i = 1; i < prices.size(); i++)
increment.push_back(prices[i] - prices[i - 1]);
int result = 0;
int cur_max = 0;
for (int i = 0; i < increment.size(); i++) {
cur_max = max(cur_max + increment[i], increment[i]);
result = max(result, cur_max);
}
return result;
}
};
// 解法二
// 思路就是每一个位置卖出股票所获得的最大收益,都是用该处的价钱减去它前面最低的价钱
class Solution {
public:
/**
* @param prices: Given an integer array
* @return: Maximum profit
*/
int maxProfit(vector<int> &prices) {
if (prices.size() <= 1) return 0;
int low = prices[0];
int max_profit = 0;
for (int i = 1; i < prices.size(); i++) {
if (prices[i] < low)
low = prices[i];
else
max_profit = max(max_profit, prices[i] - low);
}
return max_profit;
}
};

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 (ie, buy one and sell one share of the stock multiple times). However, you may not engage in multiple transactions at the same time (ie, you must sell the stock before you buy again).

1
2
3
4
5
6
7
8
9
10
11
12
13
class Solution {
public:
/**
* @param prices: Given an integer array
* @return: Maximum profit
*/
int maxProfit(vector<int> &prices) {
int result = 0;
for (int i = 1; i < prices.size(); i++)
result += (prices[i] - prices[i - 1] > 0 ? prices[i] - prices[i - 1] : 0);
return result;
}
};

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.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
/**
思路就是将问题分成两部分,我们使用一个数组forward存储第一次交易的最大利润,使用一个数组
backward存储第二次交易的最大利润。
那么forward[i]表示prices[0...i]这一段内一次交易能获得的最大利润.
backward[i]表示prices[i...n]这一段内一次交易能获得的最大利润。
结果就是将每一处的两部分相加,得到的最大的利润即为所求。
*/
class Solution {
public:
/**
* @param prices: Given an integer array
* @return: Maximum profit
*/
int maxProfit(vector<int> &prices) {
if (prices.size() <= 1) return 0;
vector<int> forward(prices.size(), 0);
int max_profit = 0;
int low = prices[0];
for (int i = 0; i < prices.size(); i++) {
if (prices[i] < low)
low = prices[i];
else
max_profit = max(max_profit, prices[i] - low);
forward[i] = max_profit;
}
vector<int> backward(prices.size(), 0);
max_profit = 0;
int high = prices[prices.size() - 1];
for (int i = prices.size() - 2; i >= 0; i--) {
if (prices[i] > high)
high = prices[i];
else
max_profit = max(max_profit, high - prices[i]);
backward[i] = max_profit;
}
int result = 0;
for (int i = 0; i < prices.size(); i++) {
result = max(result, forward[i] + backward[i]);
}
return result;
}
};

Best Time to Buy and Sell Stock IV

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 k transactions.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
/**
解法一:
dp[i, j] represents the max profit up until prices[j] using at most i transactions.
dp[i, j] = max(dp[i, j-1], prices[j] - prices[jj] + dp[i-1, jj]) { jj in range of [0, j-1] }
= max(dp[i, j-1], prices[j] + max(dp[i-1, jj] - prices[jj]))
dp[0, j] = 0; 0 transactions makes 0 profit
dp[i, 0] = 0; if there is only one price data point you can't make any transaction.
*/
class Solution {
public:
int maxProfit(int k, vector<int>& prices) {
int n = prices.size();
if (n <= 1)
return 0;
// 如果交易的次数超过了n / 2,那么就可以将问题转换为可以交换任意次,然后求最大利润
if (k >= n / 2) {
int maxProfit = 0;
for (int i = 1; i < n; i++)
maxProfit += (prices[i] - prices[i - 1] > 0 ? prices[i] - prices[i - 1] : 0);
return maxProfit;
}
vector<vector<int>> dp(k + 1, vector<int>(n, 0));
for (int i = 1; i <= k; i++) {
int localMax = dp[i - 1][0] - prices[0];
for (int j = 1; j < n; j++) {
dp[i][j] = max(dp[i][j - 1], prices[j] + localMax);
localMax = max(localMax, dp[i - 1][j] - prices[j]);
}
}
return dp[k][n - 1];
}
};