Given an array which contains random positive integers, divide the array into two parts which has the smallest diff sum, return the smallest diff sum.
This problem is solvable using dynamic programming. Using s(i, j) to stands for "there is a sum(1, i) to j" Thus, s(i, j) = s(i-1, j) || s(i, j - nums[i]);
This goes back to "coins exchange or backpacking problem again". To get the minimum difference, we can check whether there is any subsequence equals to (Sum(i, n) / 2 ... 0)
#include "header.h"
using namespace std;
// partition an array into two parts so that the two parts has mini differnce of sum.
// the two array length might not be even.
int miniDiff(vector<int>& nums) {
int sum = 0;
for(int i = 0; i < nums.size(); ++i) {
sum += nums[i];
}
int size = nums.size();
vector< vector<bool> > dp(size + 1, vector<bool>(sum + 1, false));
for(int i = 0; i <= size; ++i) {
dp[i][0] = true;
}
for(int i = 1; i <= sum; ++i) {
dp[0][i] = false;
}
for(int i = 1; i <= size; ++i) {
for(int j = 1; j <= sum; ++j) {
if(j - nums[i - 1] >= 0) {
dp[i][j] = (dp[i - 1][j] || dp[i][j - nums[i - 1]]);
} else dp[i][j] = dp[i-1][j];
}
}
for(int i = 1; i <= size; ++i) {
for(int j = sum / 2; j >= 0; --j) {
if(dp[i][j]) return sum - j - j;
}
}
return -1;
}
int main(void) {
vector<int> nums{1, 2, 4, 4};
cout << miniDiff(nums) << endl;
}
Follow Up, what if the two divided arrays has length diff with no more than 1, return the minimum difference sum. Question