Maximum Subarray III
Given an array of integers and a number k, find k non-overlapping
subarrays which have the largest sum.
The number in each subarray should be contiguous.
Return the largest sum.
Notice
The subarray should contain at least one number
class Solution {
public:
/**
* @param nums: A list of integers
* @param k: An integer denote to find k non-overlapping subarrays
* @return: An integer denote the sum of max k non-overlapping subarrays
*/
int maxSubArray(vector<int> &nums, int k) {
// write your code here
// return maxSubArray1(nums, k);
return maxSubArray2(nums, k);
}
/* local + global
* 边界条件,就是当k为0时应该是0,当其他非法情况时为INT_MIN。理解这个是难点
* 和最佳买卖股票时间那道题相似
*/
int maxSubArray1(vector<int> &nums, int k) {
// write your code here
if (nums.size() == 0 || k == 0 || k > nums.size()) {
return 0;
}
int n = nums.size();
vector<vector<int>> local(n + 1, vector<int>(k + 1, INT_MIN));
vector<vector<int>> global(n + 1, vector<int>(k + 1, INT_MIN));
// init
for (int i = 0; i <= n; i++) {
global[i][0] = 0;
local[i][0] = 0;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= k && j <= i; j++) {
local[i][j] = max(global[i - 1][j - 1],local[i - 1][j]) + nums[i - 1];
global[i][j] = max(global[i - 1][j], local[i][j]);
}
}
return global[n][k];
}
/* 这题属于动态规划里比较难的一题。首先定义状态,f[i][j]表示:在前i个元素中取出j个不重叠的子数组的和的最大值(也就
* 要将前i个元素组成的数组划分成j个部分,每个部分求最大子数组,然后相加)。状态定义好了之后,需要找到状态之间的关
* ,也就是求动态转移方程。可以将f[i][j]拆分成两部分来看,第一部分是f[x][j - 1],x为j - 1~ i
* - 1之间的任意值,表示前x个元素中取j - 1个子数组的和的最大值。第二部分是[x, x + 1, ..., i -
* 1]数组,求这个数组的maximum subarray(可以理解为在数组[0, 1, ..., x - 1, x, ..., i-
* 1]中任意切一刀,分成两部分。index为x - 1的地方就是那一刀切的地方,第一部分是[0, 1, ..., x - 1],第二部分是[x, x +
* 1, ..., i - 1])。由此得到动态转移方程为:f[i][j] = f[x][j - 1] + maxSubarray([x, x + 1, ..., i - 1])。求max
* subarray的方法可以参考maximum subarray那道题。
*/
int maxSubArray2(vector<int> &nums, int k) {
// write your code here
if (nums.size() == 0 || k == 0 || k > nums.size()) {
return 0;
}
int n = nums.size();
vector<vector<int>> dp(n + 1, vector<int>(k + 1, INT_MIN));
// init
for (int i = 0; i <= n; i++) {
dp[i][0] = 0;
}
for (int j = 1; j <= k; j++) {
for (int i = j; i <= n; i++) {
int cur_sum = 0;
int max_sum = INT_MIN;
for (int x = i - 1; x >= j - 1; x--) {
cur_sum = max(cur_sum + nums[x], nums[x]);
max_sum = max(max_sum, cur_sum);
dp[i][j] = max(dp[i][j], dp[x][j - 1] + max_sum);
}
}
}
return dp[n][k];
}
};
class Solution {
public:
/**
* @param nums: A list of integers
* @param k: An integer denote to find k non-overlapping subarrays
* @return: An integer denote the sum of max k non-overlapping subarrays
*/
int maxSubArray(vector<int> &nums, int k) {
// write your code here
int n = nums.size();
if (n == 0 || k == 0 || n < k) {
return 0;
}
// avoid overflow, use long long
vector<vector<long long>> global(n + 1, vector<long long>(k + 1, INT_MIN));
vector<vector<long long>> local(n + 1, vector<long long>(k + 1, INT_MIN));
// init
for (int i = 0; i <= n; i++) {
global[i][0] = 0;
local[i][0] = 0;
}
for (int i = 1; i <= n; i++) {
// if no condition to j <= i, INT_MIN + nums[i - 1] will overflow
for (int j = 1; j <= k; j++) {
local[i][j] = max(global[i - 1][j - 1], local[i - 1][j]) + nums[i - 1];
global[i][j] = max(global[i - 1][j], local[i][j]);
}
}
return global[n][k];
}
};
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.
Notice
You may not engage in multiple transactions at the same time (i.e., you must sell the stock before you buy again).
Example
Given prices = [4,4,6,1,1,4,2,5]
, and k = 2
, return 6
.
class Solution {
public:
/**
* @param K: An integer
* @param prices: An integer array
* @return: Maximum profit
*/
int maxProfit(int K, vector<int> &prices) {
// write your code here
return maxProfit2(K, prices);
}
int maxProfit1(int K, vector<int> &prices) {
// write your code here
if (K == 0 || prices.size() < 2) {
return 0;
}
int maxprofit = 0;
if (K >= prices.size()) {
for (int i = 1; i < prices.size(); i++) {
if (prices[i] > prices[i - 1]) {
maxprofit += (prices[i] - prices[i - 1]);
}
}
return maxprofit;
}
int n = prices.size();
vector<vector<int>> global(n, vector<int>(K + 1, 0));
vector<vector<int>> local(n, vector<int>(K + 1, 0));
for (int i = 1; i < n; i++) {
int diff = prices[i] - prices[i - 1];
for (int j = 1; j <= K; j++) {
local[i][j] = max(global[i - 1][j - 1] + max(0, diff), local[i - 1][j] + diff);
global[i][j] = max(global[i - 1][j], local[i][j]);
}
}
return global[n - 1][K];
}
int maxProfit2(int K, vector<int> &prices) {
// write your code here
if (K == 0 || prices.size() < 2) {
return 0;
}
int maxprofit = 0;
if (K >= prices.size()) {
for (int i = 1; i < prices.size(); i++) {
if (prices[i] > prices[i - 1]) {
maxprofit += (prices[i] - prices[i - 1]);
}
}
return maxprofit;
}
int n = prices.size();
vector<vector<int>> buy(n + 1, vector<int>(K + 1, INT_MIN));
vector<vector<int>> sell(n + 1, vector<int>(K + 1, 0));
for (int i = 1; i <= prices.size(); i++) {
for (int j = 1; j <= K; j++) {
buy[i][j] = max(buy[i - 1][j], sell[i][j - 1] - prices[i - 1]);
sell[i][j] = max(sell[i - 1][j], buy[i][j] + prices[i - 1]);
}
}
return sell[n][K];
}
};
class Solution {
public:
/**
* @param K: An integer
* @param prices: An integer array
* @return: Maximum profit
*/
int maxProfit(int K, vector<int> &prices) {
// write your code here
int n = prices.size();
if (K == 0 || n == 0) {
return 0;
}
if (K >= n) {
int max = 0;
for (int i = 1; i < n; i++) {
max += (prices[i] > prices[i - 1] ? prices[i] - prices[i - 1] : 0);
}
return max;
}
vector<vector<int>> local(n + 1, vector<int>(K + 1, 0));
vector<vector<int>> global(n + 1, vector<int>(K + 1, 0));
// at least need two
for (int i = 2; i <= n; i++) {
int diff = prices[i - 1] - prices[i - 2];
for (int k = 1; k <= K; k++) {
// why global can select max(0, diff) ? because for global the kth can independent to k-1
// why local need directly diff? because for local, the kth is from last kth
// need need local[i - 1][k - 1] as it always <= global[i - 1][k - 1]
local[i][k] = max(global[i - 1][k - 1] + max(0, diff), local[i - 1][k] + diff);
global[i][k] = max(global[i - 1][k], local[i][k]);
}
}
return global[n][K];
}
};