Best time to Buy and Sell Stock
我的思路:
1、给定一个数组,表示每日股价,最多只能买入和卖出一次,给出最大收益。
2、这题在算法导论的第一章就有,用的递归,这是求最大数组,每个最大数组都只有三种出现的可能。第一种是数组左边,第二种,数组右边,第三种,跨越了数组。在core函数进行递归调用,只需要对跨越中间的最大子数组进行合并。
代码如下:
#define MIN 0
struct data {
int left;
int right;
int sum;
};
class Solution {
public:
int maxProfit(vector<int> &prices) {
if (!prices.size() || prices.size() == 1)
return 0;
vector<int> changes;
int tmp;
for (int i = 0; i < prices.size() - 1; i++) {
tmp = prices[i + 1] - prices[i];
changes.push_back(tmp);
}
data ans = findMaximumSubarray(changes, 0, changes.size() - 1);
if (ans.sum < 0)
return 0;
else
return ans.sum;
}
private:
data findMaximumSubarray(vector<int> &changes, int low, int high) {
if (high == low) {
data d;
d.left = low;
d.right = high;
d.sum = changes[low];
return d;
}
else {
int mid = (low + high) / 2;
data leftd = findMaximumSubarray(changes, low, mid);
data rightd = findMaximumSubarray(changes, mid + 1, high);
data midd = findMaxCrossingSubarray(changes, low, mid, high);
if (leftd.sum >= rightd.sum && leftd.sum >= midd.sum)
return leftd;
else if (rightd.sum >= leftd.sum && rightd.sum >= midd.sum)
return rightd;
else
return midd;
}
}
data findMaxCrossingSubarray(vector<int> &changes, int low, int mid, int high) {
data d;
int leftsum = MIN;
int sum = 0;
for (int i = mid; i >= low; i--) {
sum += changes[i];
if (sum > leftsum) {
leftsum = sum;
d.left = i;
}
}
int rightsum = MIN;
sum = 0;
for (int i = mid + 1; i <= high; i++) {
sum += changes[i];
if (sum > rightsum) {
rightsum = sum;
d.right = i;
}
}
d.sum = leftsum + rightsum;
return d;
}
};
别人思路:
1、如此简单,让人心碎。遍历数组,获取数组中最小的值,如果该值不是最小,判断和之前的相比收益有没有提高,提高就改变收益。
int maxProfit(vector<int> &prices) {
if (!prices.size())
return 0;
int min = prices[0], profit = 0;
for (int i = 1; i < prices.size(); i++)
if (min > prices[i])
min = prices[i];
else
if (profit < prices[i] - min)
profit = prices[i] - min;
return profit;
}
反思:
1、其实自己就差一点就想到这个思路了,但是想起算法导论就现成了,就直接拿来用了。。。懒人穷三代。
Best Time to Buy and Sell Stock II
我的思路:
1、这题就是能买卖多次,但是下次买之前要先卖。代码类似,太简单就不贴别人的思路了,应该差不多。
int maxProfit(vector<int> &prices) {
if (prices.size() <= 1)
return 0;
int profit = 0, min = prices[0];
for (int i = 1; i < prices.size(); i++)
if (prices[i] > prices[i - 1])
profit += prices[i] - prices[i - 1];
return profit;
}
Best Time to Buy and Sell Stock III
我的思路:
1、只能买卖最多两次,就分段,可惜方向错了,就差一点点,想得还是不够多。
下面是别人的代码:
int maxProfit(vector<int> &prices) {
int length = prices.size();
if (length <= 1)
return 0;
int left[length], right[length];
memset(left, 0, sizeof(int) * length);
memset(right, 0, sizeof(int) * length);
int min = prices[0];
for (int i = 1; i < length; i++) {
left[i] = prices[i] - min > left[i - 1] ? prices[i] - min : left[i - 1];
min = prices[i] < min ? prices[i] : min;
}
int max = prices[length - 1];
for (int i = length - 2; i >= 0; i--) {
right[i] = max - prices[i] > right[i + 1] ? max - prices[i] : right[i + 1];
max = prices[i] > max ? prices[i] : max;
}
int profit = 0;
for (int i = 0; i < length; i++)
profit = left[i] + right[i] > profit ? left[i] + right[i] : profit;
return profit;
}
参考网页: 参考代码
要多尝试其他的方法!!!