When I first saw this question I got quite intrigued and a bit #mindflabergasted. This sounds like something you could get asked on interviews. A very interesting question that can give quite a lot of insight about how important requirements and clear understanding of the problem can be.

Well first off, let us start with specifications and ambiguity as per usual. There’s a little dilemma in my head about the question. It can have to meanings:

- Find whether the array can be divided AS-IS, in that exact order into two equal-sum parts?
- Find whether the array can be divided in two equal-sum parts, independent of ordering, (meaning, whether you can find two subsets of the array that are of equal sum)

For the sake of developing our solution we will try to solve both and we will see how a small assumption early on, of one or the other, can lead to a totally different thought process, solution and, hence mistake if our interviewer was asking us the other one.

## Find whether the array can be divided AS-IS, in that exact order into two equal-sum parts?

This should not be that hard, should it? So for the array to be divisible into two equal-sum parts in the same order, we need to have a point in the array where the subset to the left of that point will equal to the subset to the right and will equal to half of the total sum of the array.

Hence we can come up with an algorithm like this:

- Find the total sum of all elements in the array
- If sum is an odd number, return, the array cannot get divided
- Otherwise, go through the array keeping a left sum, until left sum is equal to half of the total sum

Sounds great! A quick analysis of the worst case scenario will give us:

**Time Complexity**– Go through the list twice –**O(n)****Space Complexity**– Keep a few variables –**O(1)**

Now let’s head into some easy coding and get this going. We’ll be using Java as per usual:

public boolean isArrayDividableInEqualSums(int[] fooBar) { if(fooBar == null) { return false; } int nSum = 0; int nLength = fooBar.length; for (int i = 0; i < nLength; ++i) { nSum += fooBar[i]; } if ((nSum % 2) != 0) { return false; // have an Odd number as a Sum, not possible to have 2 equal subsets } int nHalfSum = nSum / 2; int currSum = 0; for (int i = 0; i < nLength; ++i) { currSum += fooBar[i]; if (currSum == nHalfSum) { return true; // The set from the beginning up to and including i is equal to the elements from i+1 to the end } } return false; }

Looks great! Can we improve? There does not seem to be a way to save on Time Complexity (**O(n)**) or Space Complexity (**O(1)**), but maybe we can imrpove something stylistically.

Let's give it another try and make the code more readable.

public boolean isArrayDividableInEqualSums(int[] fooBar) { if(fooBar == null) { return false; } int nSum = getArraySum(fooBar); int nHalfSum = nSum / 2; if (!isEvenNumber(nSum)) { return false; } return isSubsetFromBeginningEqualTo(nHalfSum, fooBar); } private int getArraySum(int[] glooBar) { int nSum = 0; int nLength = glooBar.length; for (int i = 0; i < nLength; ++i) { nSum += glooBar[i]; } return nSum; } private boolean isEvenNumber(int fooMan) { if ((fooMan % 2) == 0) { return true; } return false; } private boolean isSubsetFromBeginningEqualTo(int nTarget, int[] glooWasp) { int currSum = 0; int nLength = glooWasp.length; for (int i = 0; i < nLength; ++i) { currSum += glooWasp[i]; if (currSum == nTarget) { return true; } } return false; }

Now our overall code is slightly longer, but the main method we wrote in Java is a lot shorter and a lot more readable. Indeed, I do not think we need the comments anymore, as someone just reading the code will probably understand exactly what is happening. Furthermore we have put different levels of abstraction in different methods, so our main one only shows a higher level understanding of the problem.

Sounds great, so now let us tackle the second problem...

## Find whether the array can be divided in two equal-sum subsets, independent of ordering

Well if you followed me so far, you will probably think that this is going to be just straight forward generalization of the problem we were looking at before.

You know what, I am going to leave you with this for a few hours, see if you can come up with something. Remember all work is good work, even the one that does not lead to the correct result ;). Let me know your thoughts and solutions for this part!

EDIT: As someone stated below the best approach in this case (and IMO in a lot of cases where you have a to deal with subsets (i.e. n choose k)), is dynamic algorithm. So the idea behind it is fairly simple. The execution is a bit harder. The idea is we will have a 2D array with the array Size on one axis and the possible halfSum on the other. On each cell we will know if for that array size we can reach target number (in the half sum axis).

Here you have a piece of code that I came up with while trying to come up with a solution:

public boolean canBeDividedIntoTwoEqualSubsets(int[] gooBar) { int nSum = getArraySum(gooBar); if (!isEvenNumber(nSum)) { return false; } int nSize = gooBar.length; int nHalfSum = nSum / 2; boolean[][] nSubsetSumMap = new boolean[nHalfSum + 1][nSize + 1]; for (int i = 0; i < nSize + 1; ++i) { nSubsetSumMap[0][i] = true; } for (int i = 1; i < nHalfSum + 1; ++i) { nSubsetSumMap[i][0] = false; } for (int i = 0; i < nHalfSum; ++i) { for (int j = 1; j <= nSize; ++j) { nSubsetSumMap[i][j] = nSubsetSumMap[i][j-1] || nSubsetSumMap[i - gooBar[j-1]][j - 1]; } nSubsetSumMap[0][i] = true; } return nSubsetSumMap[nHalfSum][nSize]; }

I ran it a few times and it seems to work flawlessly.

Hope you guys enjoyed it... and I'll see you guys next time ;D

#### Latest posts by Ajk (see all)

- Mergesort implementation - October 7, 2014
- Reverse Integer - October 6, 2014
- Find Longest Path in Tree - September 29, 2014