给定数组 prices,prices[i] 表示第 i 天股价。只能完成至多一笔交易(买入后卖出),求最大利润。若无利润返回 0。
设 diff[i] = prices[i+1] - prices[i] 为每日涨跌幅。买卖利润等于连续若干天涨跌幅之和。问题转化为:求差分数组的最大子段和,且下界为 0。
#include <iostream>
#include <vector>
using namespace std;
// 最大子段和(Kadane 算法变体,非负下界)
int findMax(int *list, int n) {
int maxSum = 0, sum = 0;
for (int i = 0; i < n; ++i) {
sum += list[i];
if (sum > maxSum) maxSum = sum;
else if (sum <= 0) sum = 0; // 关键:负和重置
}
return maxSum;
}
int maxProfit(vector<int> &prices) {
if (prices.empty()) return 0;
int n = prices.size();
int *diff = new int[n - 1];
for (int i = 0; i < n - 1; ++i)
diff[i] = prices[i + 1] - prices[i];
int ans = findMax(diff, n - 1);
delete[] diff;
return ans;
}
int main() {
// 测试用例
vector<int> prices = {7, 1, 5, 3, 6, 4};
cout << maxProfit(prices) << endl; // 输出 5 (第2天买入1,第5天卖出6)
return 0;
}
int maxProfit(vector<int> &prices) {
int minPrice = INT_MAX, maxProfit = 0;
for (int price : prices) {
minPrice = min(minPrice, price);
maxProfit = max(maxProfit, price - minPrice);
}
return maxProfit;
}
维护历史最低价,单次遍历即可,更简洁高效。
dp[k][i] 状态压缩本题是股票系列入门,核心在于「差分视角」与「最大子段和」的等价转化。掌握 Kadane 算法及其非负变体,可解决大量区间最优子结构问题。