From c1fe3528d6b4dfcd517fc3da777b1a09663a4546 Mon Sep 17 00:00:00 2001 From: rikim Date: Sun, 10 May 2020 14:40:00 +0900 Subject: [PATCH 01/10] Add BalancingElements with O(n^2) --- .../problem/hard/BalancingElements.java | 36 +++++++++++++++++++ .../problem/hard/BalancingElementsTest.java | 23 ++++++++++++ 2 files changed, 59 insertions(+) create mode 100644 src/main/java/com/company/problem/hard/BalancingElements.java create mode 100644 src/test/java/com/company/problem/hard/BalancingElementsTest.java diff --git a/src/main/java/com/company/problem/hard/BalancingElements.java b/src/main/java/com/company/problem/hard/BalancingElements.java new file mode 100644 index 0000000..11d109e --- /dev/null +++ b/src/main/java/com/company/problem/hard/BalancingElements.java @@ -0,0 +1,36 @@ +package com.company.problem.hard; + +public class BalancingElements { + public int countBalancingElemetns(int[] unbalancedElements) { + int count = 0; + for (int i = 0; i < unbalancedElements.length; i++) { + if (isBalanced(unbalancedElements, i)) { + count++; + } + } + return count; + } + + private boolean isBalanced(int[] elements, int balancingElementIndex) { + int oddSum = 0; + int evenSum = 0; + + for (int i = 0; i < elements.length; i++) { + if (i < balancingElementIndex) { + if (((i % 2) == 0)) { + evenSum += elements[i]; + } else { + oddSum += elements[i]; + } + } else if (i > balancingElementIndex) { + int repositioned = i - 1; + if (((repositioned % 2) == 0)) { + evenSum += elements[i]; + } else { + oddSum += elements[i]; + } + } + } + return evenSum == oddSum; + } +} \ No newline at end of file diff --git a/src/test/java/com/company/problem/hard/BalancingElementsTest.java b/src/test/java/com/company/problem/hard/BalancingElementsTest.java new file mode 100644 index 0000000..3fd9fe5 --- /dev/null +++ b/src/test/java/com/company/problem/hard/BalancingElementsTest.java @@ -0,0 +1,23 @@ +package com.company.problem.hard; + + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + + +class BalancingElementsTest { + private final BalancingElements balancingElements = new BalancingElements(); + + @Test + public void test55258_thenReturning2() { + // Given + int[] unbalancedElements = new int[]{5, 5, 2, 5, 8}; + + // When + int balancingElementsCount = balancingElements.countBalancingElemetns(unbalancedElements); + + // Then + assertThat(balancingElementsCount).isEqualTo(2); + } +} \ No newline at end of file From 78248e0ac31b894e776f4ce7a57d7805d34ec804 Mon Sep 17 00:00:00 2001 From: rikim Date: Sun, 10 May 2020 14:43:26 +0900 Subject: [PATCH 02/10] Add break condition not to traverse all --- .../com/company/problem/hard/BalancingElements.java | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/company/problem/hard/BalancingElements.java b/src/main/java/com/company/problem/hard/BalancingElements.java index 11d109e..1b03ea6 100644 --- a/src/main/java/com/company/problem/hard/BalancingElements.java +++ b/src/main/java/com/company/problem/hard/BalancingElements.java @@ -2,16 +2,21 @@ public class BalancingElements { public int countBalancingElemetns(int[] unbalancedElements) { + int wholeSum = 0; + for (int number : unbalancedElements) { + wholeSum += number; + } + int count = 0; for (int i = 0; i < unbalancedElements.length; i++) { - if (isBalanced(unbalancedElements, i)) { + if (isBalanced(unbalancedElements, i, wholeSum)) { count++; } } return count; } - private boolean isBalanced(int[] elements, int balancingElementIndex) { + private boolean isBalanced(int[] elements, int balancingElementIndex, int wholeSum) { int oddSum = 0; int evenSum = 0; @@ -30,6 +35,10 @@ private boolean isBalanced(int[] elements, int balancingElementIndex) { oddSum += elements[i]; } } + + if (oddSum > (wholeSum / 2) || (evenSum > (wholeSum / 2))) { + break; + } } return evenSum == oddSum; } From 29b9c77da4d5c32522190f8a970ffd56771f6ec2 Mon Sep 17 00:00:00 2001 From: rikim Date: Sun, 10 May 2020 14:48:18 +0900 Subject: [PATCH 03/10] Remove duplicate code --- .../problem/hard/BalancingElements.java | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/main/java/com/company/problem/hard/BalancingElements.java b/src/main/java/com/company/problem/hard/BalancingElements.java index 1b03ea6..e778ecd 100644 --- a/src/main/java/com/company/problem/hard/BalancingElements.java +++ b/src/main/java/com/company/problem/hard/BalancingElements.java @@ -21,19 +21,16 @@ private boolean isBalanced(int[] elements, int balancingElementIndex, int wholeS int evenSum = 0; for (int i = 0; i < elements.length; i++) { - if (i < balancingElementIndex) { - if (((i % 2) == 0)) { - evenSum += elements[i]; - } else { - oddSum += elements[i]; - } - } else if (i > balancingElementIndex) { - int repositioned = i - 1; - if (((repositioned % 2) == 0)) { - evenSum += elements[i]; - } else { - oddSum += elements[i]; - } + if (balancingElementIndex == i) { + continue; + } + + int repositioned = (i > balancingElementIndex) ? i - 1 : i; + + if ((repositioned % 2) == 0) { + evenSum += elements[i]; + } else { + oddSum += elements[i]; } if (oddSum > (wholeSum / 2) || (evenSum > (wholeSum / 2))) { From 6e75645b69c90ebfc090646f70ba2e3151084bf9 Mon Sep 17 00:00:00 2001 From: rikim Date: Sun, 10 May 2020 14:48:52 +0900 Subject: [PATCH 04/10] Rename local var --- src/main/java/com/company/problem/hard/BalancingElements.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/company/problem/hard/BalancingElements.java b/src/main/java/com/company/problem/hard/BalancingElements.java index e778ecd..d007309 100644 --- a/src/main/java/com/company/problem/hard/BalancingElements.java +++ b/src/main/java/com/company/problem/hard/BalancingElements.java @@ -25,9 +25,9 @@ private boolean isBalanced(int[] elements, int balancingElementIndex, int wholeS continue; } - int repositioned = (i > balancingElementIndex) ? i - 1 : i; + int leftShifted = (i > balancingElementIndex) ? i - 1 : i; - if ((repositioned % 2) == 0) { + if ((leftShifted % 2) == 0) { evenSum += elements[i]; } else { oddSum += elements[i]; From b2642d28b7ec62bf95931c36c82a2f0aa427a5c3 Mon Sep 17 00:00:00 2001 From: rikim Date: Sun, 10 May 2020 15:26:31 +0900 Subject: [PATCH 05/10] Add problem description --- .../java/com/company/problem/hard/BalancingElements.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/main/java/com/company/problem/hard/BalancingElements.java b/src/main/java/com/company/problem/hard/BalancingElements.java index d007309..0af5e5f 100644 --- a/src/main/java/com/company/problem/hard/BalancingElements.java +++ b/src/main/java/com/company/problem/hard/BalancingElements.java @@ -1,5 +1,11 @@ package com.company.problem.hard; +/** + * When one of the elements is removed from an array and the higher indexed elements shift to the left and fill the empty space. + * In the case, when the sum of even-indexed elements is equal to the sum of the odd-indexed, the removed element is called balancing element. + * Expected answer: + * a count of balancing elements in a given array. + */ public class BalancingElements { public int countBalancingElemetns(int[] unbalancedElements) { int wholeSum = 0; From cbe9d356c92364e380fcd835219f05f8a28d7a4e Mon Sep 17 00:00:00 2001 From: rikim Date: Sun, 10 May 2020 15:50:00 +0900 Subject: [PATCH 06/10] Check the sum is even number except a deleted element --- .../java/com/company/problem/hard/BalancingElements.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/company/problem/hard/BalancingElements.java b/src/main/java/com/company/problem/hard/BalancingElements.java index 0af5e5f..3d9150c 100644 --- a/src/main/java/com/company/problem/hard/BalancingElements.java +++ b/src/main/java/com/company/problem/hard/BalancingElements.java @@ -1,5 +1,7 @@ package com.company.problem.hard; +import java.util.ArrayList; + /** * When one of the elements is removed from an array and the higher indexed elements shift to the left and fill the empty space. * In the case, when the sum of even-indexed elements is equal to the sum of the odd-indexed, the removed element is called balancing element. @@ -14,7 +16,12 @@ public int countBalancingElemetns(int[] unbalancedElements) { } int count = 0; - for (int i = 0; i < unbalancedElements.length; i++) { + for (int i = 0; i < unbalancedElements.length; i++) { //O(n^2) + + if (((wholeSum - unbalancedElements[i]) % 2) != 0) { + continue; + } + if (isBalanced(unbalancedElements, i, wholeSum)) { count++; } From 3615f32821d7b71dbcccab5c64796e46ba8c7ad6 Mon Sep 17 00:00:00 2001 From: rikim Date: Sun, 10 May 2020 15:59:28 +0900 Subject: [PATCH 07/10] Move checking the sum of the rest elements to isBalanced --- .../java/com/company/problem/hard/BalancingElements.java | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/main/java/com/company/problem/hard/BalancingElements.java b/src/main/java/com/company/problem/hard/BalancingElements.java index 3d9150c..1f0a6d6 100644 --- a/src/main/java/com/company/problem/hard/BalancingElements.java +++ b/src/main/java/com/company/problem/hard/BalancingElements.java @@ -17,11 +17,6 @@ public int countBalancingElemetns(int[] unbalancedElements) { int count = 0; for (int i = 0; i < unbalancedElements.length; i++) { //O(n^2) - - if (((wholeSum - unbalancedElements[i]) % 2) != 0) { - continue; - } - if (isBalanced(unbalancedElements, i, wholeSum)) { count++; } @@ -33,6 +28,10 @@ private boolean isBalanced(int[] elements, int balancingElementIndex, int wholeS int oddSum = 0; int evenSum = 0; + if (((wholeSum - elements[balancingElementIndex]) % 2) != 0) { + return false; + } + for (int i = 0; i < elements.length; i++) { if (balancingElementIndex == i) { continue; From 4ce2a9ee4154f2aa368e9736f99347ae84d8c301 Mon Sep 17 00:00:00 2001 From: rikim Date: Sun, 10 May 2020 18:00:22 +0900 Subject: [PATCH 08/10] Optimize isBalanced time-complexity to constant time from O(n) by using partialSum cache --- .../problem/hard/BalancingElements.java | 68 +++++++++++-------- 1 file changed, 41 insertions(+), 27 deletions(-) diff --git a/src/main/java/com/company/problem/hard/BalancingElements.java b/src/main/java/com/company/problem/hard/BalancingElements.java index 1f0a6d6..1b4f8c4 100644 --- a/src/main/java/com/company/problem/hard/BalancingElements.java +++ b/src/main/java/com/company/problem/hard/BalancingElements.java @@ -1,7 +1,5 @@ package com.company.problem.hard; -import java.util.ArrayList; - /** * When one of the elements is removed from an array and the higher indexed elements shift to the left and fill the empty space. * In the case, when the sum of even-indexed elements is equal to the sum of the odd-indexed, the removed element is called balancing element. @@ -10,45 +8,61 @@ */ public class BalancingElements { public int countBalancingElemetns(int[] unbalancedElements) { - int wholeSum = 0; - for (int number : unbalancedElements) { - wholeSum += number; - } + int[][] partialSum = buildPartialOddAndEvenSum(unbalancedElements); //O(n) int count = 0; - for (int i = 0; i < unbalancedElements.length; i++) { //O(n^2) - if (isBalanced(unbalancedElements, i, wholeSum)) { + for (int i = 0; i < unbalancedElements.length; i++) { //O(n) + if (isBalanced(i, partialSum.clone())) { // c count++; } } return count; } - private boolean isBalanced(int[] elements, int balancingElementIndex, int wholeSum) { - int oddSum = 0; - int evenSum = 0; + private int[][] buildPartialOddAndEvenSum(int[] unbalancedElements) { + int wholeOddSum = 0; + int wholeEvenSum = 0; + int[][] partialSum = new int[unbalancedElements.length][2]; + for (int i = 0; i < unbalancedElements.length; i++) {//O(n) + int number = unbalancedElements[i]; + if ((i % 2) == 0) { + wholeEvenSum += number; + if (i == 0) { + partialSum[0][0] = wholeEvenSum; + partialSum[0][1] = 0; - if (((wholeSum - elements[balancingElementIndex]) % 2) != 0) { - return false; + } else { + partialSum[i][0] = wholeEvenSum; + partialSum[i][1] = partialSum[i - 1][1]; + } + } else { + wholeOddSum += number; + partialSum[i][0] = partialSum[i - 1][0]; + partialSum[i][1] = wholeOddSum; + } } + return partialSum; + } - for (int i = 0; i < elements.length; i++) { - if (balancingElementIndex == i) { - continue; - } + private boolean isBalanced(int indexToRemove, int[][] partialSum) { + int lastIndex = partialSum.length - 1; - int leftShifted = (i > balancingElementIndex) ? i - 1 : i; + int[] partialSumBeforeElement; + if (indexToRemove == 0) { + partialSumBeforeElement = new int[]{0, 0}; + } else { + partialSumBeforeElement = partialSum[indexToRemove - 1]; + } - if ((leftShifted % 2) == 0) { - evenSum += elements[i]; - } else { - oddSum += elements[i]; - } + int[] partialSumAfterRemovedElement = {partialSum[lastIndex][0] - partialSum[indexToRemove][0], partialSum[lastIndex][1] - partialSum[indexToRemove][1]}; - if (oddSum > (wholeSum / 2) || (evenSum > (wholeSum / 2))) { - break; - } - } + int even = partialSumAfterRemovedElement[0]; + partialSumAfterRemovedElement[0] = partialSumAfterRemovedElement[1]; + partialSumAfterRemovedElement[1] = even; + + int evenSum = partialSumAfterRemovedElement[0] + partialSumBeforeElement[0]; + int oddSum = partialSumAfterRemovedElement[1] + partialSumBeforeElement[1]; + System.out.println("indexToRemove:" + indexToRemove + " oddSum: " + oddSum + " evenSum: " + evenSum); return evenSum == oddSum; } } \ No newline at end of file From dbe646960292562169fc603ebce22d2784e67e95 Mon Sep 17 00:00:00 2001 From: rikim Date: Sun, 10 May 2020 18:02:29 +0900 Subject: [PATCH 09/10] Add method description --- .../java/com/company/problem/hard/BalancingElements.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/main/java/com/company/problem/hard/BalancingElements.java b/src/main/java/com/company/problem/hard/BalancingElements.java index 1b4f8c4..7136fc0 100644 --- a/src/main/java/com/company/problem/hard/BalancingElements.java +++ b/src/main/java/com/company/problem/hard/BalancingElements.java @@ -7,6 +7,13 @@ * a count of balancing elements in a given array. */ public class BalancingElements { + + /** + * Time complexity 2 * O(n) * c => O(n) + * + * @param unbalancedElements + * @return the count of balancing elements + */ public int countBalancingElemetns(int[] unbalancedElements) { int[][] partialSum = buildPartialOddAndEvenSum(unbalancedElements); //O(n) From fc56b2ad4ad925e036d5a7efa55b29f1e9cbd2a7 Mon Sep 17 00:00:00 2001 From: rikim Date: Sun, 10 May 2020 18:27:22 +0900 Subject: [PATCH 10/10] Add doucument about how to rebuild partialSum --- .../problem/hard/BalancingElements.java | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/src/main/java/com/company/problem/hard/BalancingElements.java b/src/main/java/com/company/problem/hard/BalancingElements.java index 7136fc0..aff5e62 100644 --- a/src/main/java/com/company/problem/hard/BalancingElements.java +++ b/src/main/java/com/company/problem/hard/BalancingElements.java @@ -72,4 +72,47 @@ private boolean isBalanced(int indexToRemove, int[][] partialSum) { System.out.println("indexToRemove:" + indexToRemove + " oddSum: " + oddSum + " evenSum: " + evenSum); return evenSum == oddSum; } + + /** + * The WAY OF REBUILDING partialSum after removal + * arr: [0 1 2 3 4 5] + * partialEvenAndOddSum + * = [[0], [0]], [[0], [1]], [[0 + 2], [1]] [[0 + 2], [1 + 3]] [[0 + 2 + 4], [1 + 3]], [[0 + 2 + 4], [1 + 3 + 5]] + * + * CASE 1: Remove 0 from arr + * + * 0 removed and shift higher indexed elements to the left + * arrAfterRemove: [1 2 3 4 5] + * + * Rebuilt partialSum after removal + * [[1],[0]], [[1], [2]], [[1,3], [2]], [[1,3], [2. 4]], [[1, 3, 5], [2, 4]] + * + * + * Rebuild the last element partialSum + * [[0 + 2 + 4], [1 + 3 + 5] => [[1, 3, 5], [2, 4]] + * + * 1. Subtract by partialSum till the removed element + * partialSum[last] - partialSum[0] + * = [[0 + 2 + 4], [1 + 3 + 5]] - [[0], [0]] = [[2 + 4], [1 + 3 + 5]] + * + * 2. Swap the position + * partialSum[last][0] = partialSum[last][1] partialSum[last][1] = partialSum[last][0] + * [[2 + 4], [1 + 3 + 5]] => [[1 + 3 + 5], [2 + 4]] // + * + * + * + * CASE 2: Remove 3 located in the middle of arr + * 3 removed and shift higher indexed elements to the left + * [[0], []], [[0], [1]], [[0, 2], [1]] [[0, 2, 4], [1, 3]], [[0, 2, 4], [1, 3, 5]] + * + * 1. Subtract by partialSum till the removed element + * partialSum[last] - partialSum[0] + * = [[0, 2, 4], [1, 3, 5]] - [[0, 2], [1, 3]] = [[4], [5]] + * 2. Swap the position + * [[4], [5]] => [[5], [4]] + * + * 3. Sum partialSum before the removed element + * [[5], [4]] + [[0 + 2], [1]] = [0 + 2 + 5], [1 + 4] + */ + } \ No newline at end of file