难度:困难
暴力超时解法
首先想到了比较暴力的方法,将数组在不同位置进行分段,然后分别计算两段的最大收益,最后选取最大的那个。思想都在代码里。
结果应该是正确,但超时了的解法:
class Solution {
public:
// get the index of max value in prices[left, right]
int findMaxIndex(vector<int>& prices, int left, int right){
int max_index = left;
int max_value = prices[left];
for(int i = left; i <= right; i++){
if(prices[i] > max_value){
max_value = prices[i];
max_index = i;
}
}
return max_index;
}
// get the index of min value in prices[left, right]
int findMinIndex(vector<int>& prices, int left, int right){
int min_index = left;
int min_value = prices[left];
for(int i = left; i <= right; i++){
if(prices[i] < min_value){
min_value = prices[i];
min_index = i;
}
}
return min_index;
}
// get the max profit in prices[left, right]
int maxProfit_part(vector<int>& prices, int left, int right){
if(left >= right)return 0;
int max_index = findMaxIndex(prices, left, right);
int min_index = findMinIndex(prices, left, right);
// cout << "------------- "<< left <<" - " << right << "---------------" <<endl;
// cout << "max_index:" << max_index << " " << prices[max_index]<< endl;
// cout << "min_index:" << min_index << " " << prices[min_index] << endl;
if(prices[max_index] == prices[min_index])return 0;
if(min_index < max_index)return prices[max_index] - prices[min_index];
int price1 = maxProfit_part(prices, left, max_index);
int price2 = maxProfit_part(prices, max_index + 1, min_index - 1);
int price3 = maxProfit_part(prices, min_index, right);
if(price1 >= price2 && price1 >= price3)return price1;
else if(price2 > price3)return price2;
else return price3;
}
int maxProfit(vector<int>& prices) {
int len = prices.size();
if(len <= 0)return 0;
int max_price = 0;
for(int i = 0; i < len - 1; i++){
int result;
if(i == 0){
// cout << "iteration:" << i << " [" << i << "," << len - 1 << "]" << endl;
result =maxProfit_part(prices, i, len - 1);
}
else{
// cout << "iteration:" << i << " [" << 0 << "," << i << "]" << endl;
// cout << " [" << i+1 << "," << len - 1 << "]" << endl;
result = maxProfit_part(prices, 0, i) + maxProfit_part(prices, i + 1, len - 1);
}
if(result > max_price)max_price = result;
}
return max_price;
}
};
将其改为动态规划的形式,但是空间不足,说明这个算法的设计不是最优的。
int profits[10001][10001];
class Solution {
public:
// get the index of max value in prices[left, right]
int findMaxIndex(vector<int>& prices, int left, int right){
int max_index = left;
int max_value = prices[left];
for(int i = left; i <= right; i++){
if(prices[i] > max_value){
max_value = prices[i];
max_index = i;
}
}
return max_index;
}
// get the index of min value in prices[left, right]
int findMinIndex(vector<int>& prices, int left, int right){
int min_index = left;
int min_value = prices[left];
for(int i = left; i <= right; i++){
if(prices[i] < min_value){
min_value = prices[i];
min_index = i;
}
}
return min_index;
}
int maxProfit(vector<int>& prices) {
int len = prices.size();
if(len <= 1)return 0;
int max_price = 0;
for(int i = 0; i< len; i++){
profits[i][i] = 0;
}
for(int k = 1; k < len; k++){
for(int i = 0; i < len - k; i++){
int j = i + k;
int max_index = findMaxIndex(prices, i, j);
int min_index = findMinIndex(prices, i, j);
if(prices[max_index] == prices[min_index]){
profits[i][j] = 0;
}
else if(min_index < max_index){
profits[i][j] = prices[max_index] - prices[min_index];
}
else{
int price1 = profits[i][max_index];
int price2 = profits[max_index + 1][min_index - 1];
int price3 = profits[min_index][j];
if(price1 >= price2 && price1 >= price3)profits[i][j] = price1;
else if(price2 > price3)profits[i][j] = price2;
else profits[i][j] = price3;
}
// cout << i << "-" << j << ":" << profits[i][j] << endl;
}
}
for(int i = 0; i < len - 1; i++){
int result;
if(i == 0){
// cout << "iteration:" << i << " [" << i << "," << len - 1 << "]" << endl;
result = profits[i][len - 1];
cout << result << endl;
}
else{
// cout << "iteration:" << i << " [" << 0 << "," << i << "]" << endl;
// cout << " [" << i+1 << "," << len - 1 << "]" << endl;
int result1 = profits[0][i];
int result2 = profits[i + 1][len - 1];
result = result1 + result2;
// cout << result1 << " " << result2 << " " << result << endl;
}
if(result > max_price)max_price = result;
}
return max_price;
}
};
正确解法
方法1
参考https://blog.csdn.net/qq_17550379/article/details/83620892。
看了这个思路,感觉智商被碾压,代码太简单了
我的实现:
class Solution {
public:
int max_num(int a, int b){
return a>b?a:b;
}
int maxProfit(vector<int>& prices) {
int len = prices.size();
if(len <= 1)return 0;
int in_profit1 = -prices[0], out_profit1 = 0, in_profit2 = -prices[0], out_profit2 = 0;
for(int i = 0; i < len; i++){
in_profit1 = max_num(in_profit1, -prices[i]);
out_profit1 = max_num(out_profit1, in_profit1 + prices[i]);
in_profit2 = max_num(in_profit2, out_profit1 - prices[i]);
out_profit2 = max_num(out_profit2, in_profit2 + prices[i]);
}
return out_profit2;
}
};
方法2
参考:https://blog.csdn.net/qq_41231926/article/details/84451773
- 超时代码:
class Solution {
public:
int max_num(int a, int b){
return a>b?a:b;
}
int profits[3][100001];
int maxProfit(vector<int>& prices) {
int len = prices.size();
if(len <= 1)return 0;
for(int k = 0; k < 2; k++){
profits[k][0] = 0;
for(int i = 1;i < len; i++){
int min_price = prices[0];
for(int j = 1; j < i; j++){
if(k == 0){
min_price = min(min_price, prices[j]);
}
else{
min_price = min(min_price, prices[j] - profits[k - 1][j - 1]);
}
}
profits[k][i] = max_num(profits[k][i - 1], prices[i] - min_price);
}
}
return profits[1][len - 1];
}
};
- 改进一下,通过代码:
class Solution {
public:
int max_num(int a, int b){
return a>b?a:b;
}
int maxProfit(vector<int>& prices) {
int len = prices.size();
int result = 0;
if(len <= 1)return result;
int profits[3][100001] = {
0};
for(int k = 0; k < 2; k++){
profits[k][0] = 0;
int min_price = prices[0];
for(int i = 1;i < len; i++){
profits[k][i] = max_num(profits[k][i - 1], prices[i] - min_price);
if(k == 0){
min_price = min(min_price, prices[i]);
}
else{
min_price = min(min_price, prices[i] - profits[k - 1][i - 1]);
}
}
}
return profits[1][len - 1];
}
};