Codility Tape Equilibrium











up vote
1
down vote

favorite












This question is related to this one, since it's about the same Codility exercise (Tape Equilibrium instructions): Time complexity of tape equilibirum



Basically, given an integer array, the objective is to split it at a given index into 2 smaller arrays, sum each arrays and find the smallest absolute difference possible between the 2 arrays.



Example:



I have an array A = {3, 1, 2, 4, 3}.



If I split at index 1, left array is {3} and right array is {1, 2, 4, 3}. The absolute difference is |(3) - (1 + 2 + 4 + 3)| = 7.



The smallest possible split is with index 3, where left array is {3, 1, 2} and right array is {4, 3} and the absolute difference is |(3 + 1 + 2) - (4 + 3)| = 1.



I have written the following code:



class Solution {

private Map<Integer, Integer> lowerSplitSumValue;
private Map<Integer, Integer> upperSplitSumValue;

public void loadSplitSumValue(int A) {
if (lowerSplitSumValue == null) {
lowerSplitSumValue = new HashMap<Integer, Integer>();
upperSplitSumValue = new HashMap<Integer, Integer>();
}

for (int i = 1 ; i < A.length ; ++i) {
if (i != 1) {
lowerSplitSumValue.put(i, lowerSplitSumValue.get(i - 1) + A[i - 1]);
upperSplitSumValue.put(A.length - i, upperSplitSumValue.get(A.length - i + 1) + A[A.length - i]);
} else {
lowerSplitSumValue.put(i, A[0]);
upperSplitSumValue.put(A.length - i, A[A.length - 1]);
}
}
}

public int solution(int A) {
if (A == null || A.length < 1) {
return 0;
}

loadSplitSumValue(A);

int smallestValue = Math.abs(lowerSplitSumValue.get(1) - upperSplitSumValue.get(1));

for (int i = 2 ; i < A.length - 1 ; ++i) {
int newValue = Math.abs(lowerSplitSumValue.get(i) - upperSplitSumValue.get(i));

if (newValue < smallestValue) {
smallestValue = newValue;
}
}

return smallestValue;
}
}


From my understanding, this should be at most $O(N*log(N))$:




  • I'm using several for loops, but none of them are nested, so their complexity is $O(N)$.

  • Each for loops are accessing a Map, which to my understanding have a general complexity of $O(log(N))$.


However, when I submit this code on Codility, the compiler says only 33% of the performance tests passed, and the complexity is $O(N*N)$, which is way higher than what I expected...



Why does Codility consider my algorithm to be $O(N*N)$? Java Maps aren't supposed to be that slow...










share|improve this question




















  • 2




    Welcome to Code Review! We generally provide open-ended feedback about all aspects of your code (see "Do I want feedback about any or all facets of the code?" in the help center). The current wording of your question suggests you only want to know why the computational complexity of your code is not what you expect.
    – Graham
    Nov 20 at 13:47








  • 1




    It isn't O(n*n) but Codility only estimates it by runtime. Is there any reason for using Map<Integer, Integer> instead of just int lowerSplitSumValue? You know the array will have same length as int A. Using Map in such case brings no benefits, it is only slower. Maybe that is enough to exceed time limits on task.
    – user158037
    Nov 20 at 15:28






  • 1




    Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles.
    – Toby Speight
    Nov 21 at 8:17






  • 2




    "What is the complexity of my algorithm?" sounds like you don't understand your own code. "*Can I reduce the algorithmic complexity?" would sound more like (part of) a review request. You also should attempt to explain (in your own words) the problem you're solving, rather than just relying on a link.
    – Toby Speight
    Nov 21 at 8:45








  • 1




    All I can suggest is simply stating that you and the judge disagree on the complexity (and justify your reasoning), and let the reviewers choose whether to pick up on that. BTW, you should be able to solve this with an algorithm that scales as O(n), with no other containers needed. Think about how the left sum and right sum each change as you move one position along the input.
    – Toby Speight
    Nov 21 at 8:55















up vote
1
down vote

favorite












This question is related to this one, since it's about the same Codility exercise (Tape Equilibrium instructions): Time complexity of tape equilibirum



Basically, given an integer array, the objective is to split it at a given index into 2 smaller arrays, sum each arrays and find the smallest absolute difference possible between the 2 arrays.



Example:



I have an array A = {3, 1, 2, 4, 3}.



If I split at index 1, left array is {3} and right array is {1, 2, 4, 3}. The absolute difference is |(3) - (1 + 2 + 4 + 3)| = 7.



The smallest possible split is with index 3, where left array is {3, 1, 2} and right array is {4, 3} and the absolute difference is |(3 + 1 + 2) - (4 + 3)| = 1.



I have written the following code:



class Solution {

private Map<Integer, Integer> lowerSplitSumValue;
private Map<Integer, Integer> upperSplitSumValue;

public void loadSplitSumValue(int A) {
if (lowerSplitSumValue == null) {
lowerSplitSumValue = new HashMap<Integer, Integer>();
upperSplitSumValue = new HashMap<Integer, Integer>();
}

for (int i = 1 ; i < A.length ; ++i) {
if (i != 1) {
lowerSplitSumValue.put(i, lowerSplitSumValue.get(i - 1) + A[i - 1]);
upperSplitSumValue.put(A.length - i, upperSplitSumValue.get(A.length - i + 1) + A[A.length - i]);
} else {
lowerSplitSumValue.put(i, A[0]);
upperSplitSumValue.put(A.length - i, A[A.length - 1]);
}
}
}

public int solution(int A) {
if (A == null || A.length < 1) {
return 0;
}

loadSplitSumValue(A);

int smallestValue = Math.abs(lowerSplitSumValue.get(1) - upperSplitSumValue.get(1));

for (int i = 2 ; i < A.length - 1 ; ++i) {
int newValue = Math.abs(lowerSplitSumValue.get(i) - upperSplitSumValue.get(i));

if (newValue < smallestValue) {
smallestValue = newValue;
}
}

return smallestValue;
}
}


From my understanding, this should be at most $O(N*log(N))$:




  • I'm using several for loops, but none of them are nested, so their complexity is $O(N)$.

  • Each for loops are accessing a Map, which to my understanding have a general complexity of $O(log(N))$.


However, when I submit this code on Codility, the compiler says only 33% of the performance tests passed, and the complexity is $O(N*N)$, which is way higher than what I expected...



Why does Codility consider my algorithm to be $O(N*N)$? Java Maps aren't supposed to be that slow...










share|improve this question




















  • 2




    Welcome to Code Review! We generally provide open-ended feedback about all aspects of your code (see "Do I want feedback about any or all facets of the code?" in the help center). The current wording of your question suggests you only want to know why the computational complexity of your code is not what you expect.
    – Graham
    Nov 20 at 13:47








  • 1




    It isn't O(n*n) but Codility only estimates it by runtime. Is there any reason for using Map<Integer, Integer> instead of just int lowerSplitSumValue? You know the array will have same length as int A. Using Map in such case brings no benefits, it is only slower. Maybe that is enough to exceed time limits on task.
    – user158037
    Nov 20 at 15:28






  • 1




    Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles.
    – Toby Speight
    Nov 21 at 8:17






  • 2




    "What is the complexity of my algorithm?" sounds like you don't understand your own code. "*Can I reduce the algorithmic complexity?" would sound more like (part of) a review request. You also should attempt to explain (in your own words) the problem you're solving, rather than just relying on a link.
    – Toby Speight
    Nov 21 at 8:45








  • 1




    All I can suggest is simply stating that you and the judge disagree on the complexity (and justify your reasoning), and let the reviewers choose whether to pick up on that. BTW, you should be able to solve this with an algorithm that scales as O(n), with no other containers needed. Think about how the left sum and right sum each change as you move one position along the input.
    – Toby Speight
    Nov 21 at 8:55













up vote
1
down vote

favorite









up vote
1
down vote

favorite











This question is related to this one, since it's about the same Codility exercise (Tape Equilibrium instructions): Time complexity of tape equilibirum



Basically, given an integer array, the objective is to split it at a given index into 2 smaller arrays, sum each arrays and find the smallest absolute difference possible between the 2 arrays.



Example:



I have an array A = {3, 1, 2, 4, 3}.



If I split at index 1, left array is {3} and right array is {1, 2, 4, 3}. The absolute difference is |(3) - (1 + 2 + 4 + 3)| = 7.



The smallest possible split is with index 3, where left array is {3, 1, 2} and right array is {4, 3} and the absolute difference is |(3 + 1 + 2) - (4 + 3)| = 1.



I have written the following code:



class Solution {

private Map<Integer, Integer> lowerSplitSumValue;
private Map<Integer, Integer> upperSplitSumValue;

public void loadSplitSumValue(int A) {
if (lowerSplitSumValue == null) {
lowerSplitSumValue = new HashMap<Integer, Integer>();
upperSplitSumValue = new HashMap<Integer, Integer>();
}

for (int i = 1 ; i < A.length ; ++i) {
if (i != 1) {
lowerSplitSumValue.put(i, lowerSplitSumValue.get(i - 1) + A[i - 1]);
upperSplitSumValue.put(A.length - i, upperSplitSumValue.get(A.length - i + 1) + A[A.length - i]);
} else {
lowerSplitSumValue.put(i, A[0]);
upperSplitSumValue.put(A.length - i, A[A.length - 1]);
}
}
}

public int solution(int A) {
if (A == null || A.length < 1) {
return 0;
}

loadSplitSumValue(A);

int smallestValue = Math.abs(lowerSplitSumValue.get(1) - upperSplitSumValue.get(1));

for (int i = 2 ; i < A.length - 1 ; ++i) {
int newValue = Math.abs(lowerSplitSumValue.get(i) - upperSplitSumValue.get(i));

if (newValue < smallestValue) {
smallestValue = newValue;
}
}

return smallestValue;
}
}


From my understanding, this should be at most $O(N*log(N))$:




  • I'm using several for loops, but none of them are nested, so their complexity is $O(N)$.

  • Each for loops are accessing a Map, which to my understanding have a general complexity of $O(log(N))$.


However, when I submit this code on Codility, the compiler says only 33% of the performance tests passed, and the complexity is $O(N*N)$, which is way higher than what I expected...



Why does Codility consider my algorithm to be $O(N*N)$? Java Maps aren't supposed to be that slow...










share|improve this question















This question is related to this one, since it's about the same Codility exercise (Tape Equilibrium instructions): Time complexity of tape equilibirum



Basically, given an integer array, the objective is to split it at a given index into 2 smaller arrays, sum each arrays and find the smallest absolute difference possible between the 2 arrays.



Example:



I have an array A = {3, 1, 2, 4, 3}.



If I split at index 1, left array is {3} and right array is {1, 2, 4, 3}. The absolute difference is |(3) - (1 + 2 + 4 + 3)| = 7.



The smallest possible split is with index 3, where left array is {3, 1, 2} and right array is {4, 3} and the absolute difference is |(3 + 1 + 2) - (4 + 3)| = 1.



I have written the following code:



class Solution {

private Map<Integer, Integer> lowerSplitSumValue;
private Map<Integer, Integer> upperSplitSumValue;

public void loadSplitSumValue(int A) {
if (lowerSplitSumValue == null) {
lowerSplitSumValue = new HashMap<Integer, Integer>();
upperSplitSumValue = new HashMap<Integer, Integer>();
}

for (int i = 1 ; i < A.length ; ++i) {
if (i != 1) {
lowerSplitSumValue.put(i, lowerSplitSumValue.get(i - 1) + A[i - 1]);
upperSplitSumValue.put(A.length - i, upperSplitSumValue.get(A.length - i + 1) + A[A.length - i]);
} else {
lowerSplitSumValue.put(i, A[0]);
upperSplitSumValue.put(A.length - i, A[A.length - 1]);
}
}
}

public int solution(int A) {
if (A == null || A.length < 1) {
return 0;
}

loadSplitSumValue(A);

int smallestValue = Math.abs(lowerSplitSumValue.get(1) - upperSplitSumValue.get(1));

for (int i = 2 ; i < A.length - 1 ; ++i) {
int newValue = Math.abs(lowerSplitSumValue.get(i) - upperSplitSumValue.get(i));

if (newValue < smallestValue) {
smallestValue = newValue;
}
}

return smallestValue;
}
}


From my understanding, this should be at most $O(N*log(N))$:




  • I'm using several for loops, but none of them are nested, so their complexity is $O(N)$.

  • Each for loops are accessing a Map, which to my understanding have a general complexity of $O(log(N))$.


However, when I submit this code on Codility, the compiler says only 33% of the performance tests passed, and the complexity is $O(N*N)$, which is way higher than what I expected...



Why does Codility consider my algorithm to be $O(N*N)$? Java Maps aren't supposed to be that slow...







java complexity






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited yesterday









Jamal

30.2k11115226




30.2k11115226










asked Nov 20 at 12:54









Clockwork

1064




1064








  • 2




    Welcome to Code Review! We generally provide open-ended feedback about all aspects of your code (see "Do I want feedback about any or all facets of the code?" in the help center). The current wording of your question suggests you only want to know why the computational complexity of your code is not what you expect.
    – Graham
    Nov 20 at 13:47








  • 1




    It isn't O(n*n) but Codility only estimates it by runtime. Is there any reason for using Map<Integer, Integer> instead of just int lowerSplitSumValue? You know the array will have same length as int A. Using Map in such case brings no benefits, it is only slower. Maybe that is enough to exceed time limits on task.
    – user158037
    Nov 20 at 15:28






  • 1




    Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles.
    – Toby Speight
    Nov 21 at 8:17






  • 2




    "What is the complexity of my algorithm?" sounds like you don't understand your own code. "*Can I reduce the algorithmic complexity?" would sound more like (part of) a review request. You also should attempt to explain (in your own words) the problem you're solving, rather than just relying on a link.
    – Toby Speight
    Nov 21 at 8:45








  • 1




    All I can suggest is simply stating that you and the judge disagree on the complexity (and justify your reasoning), and let the reviewers choose whether to pick up on that. BTW, you should be able to solve this with an algorithm that scales as O(n), with no other containers needed. Think about how the left sum and right sum each change as you move one position along the input.
    – Toby Speight
    Nov 21 at 8:55














  • 2




    Welcome to Code Review! We generally provide open-ended feedback about all aspects of your code (see "Do I want feedback about any or all facets of the code?" in the help center). The current wording of your question suggests you only want to know why the computational complexity of your code is not what you expect.
    – Graham
    Nov 20 at 13:47








  • 1




    It isn't O(n*n) but Codility only estimates it by runtime. Is there any reason for using Map<Integer, Integer> instead of just int lowerSplitSumValue? You know the array will have same length as int A. Using Map in such case brings no benefits, it is only slower. Maybe that is enough to exceed time limits on task.
    – user158037
    Nov 20 at 15:28






  • 1




    Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles.
    – Toby Speight
    Nov 21 at 8:17






  • 2




    "What is the complexity of my algorithm?" sounds like you don't understand your own code. "*Can I reduce the algorithmic complexity?" would sound more like (part of) a review request. You also should attempt to explain (in your own words) the problem you're solving, rather than just relying on a link.
    – Toby Speight
    Nov 21 at 8:45








  • 1




    All I can suggest is simply stating that you and the judge disagree on the complexity (and justify your reasoning), and let the reviewers choose whether to pick up on that. BTW, you should be able to solve this with an algorithm that scales as O(n), with no other containers needed. Think about how the left sum and right sum each change as you move one position along the input.
    – Toby Speight
    Nov 21 at 8:55








2




2




Welcome to Code Review! We generally provide open-ended feedback about all aspects of your code (see "Do I want feedback about any or all facets of the code?" in the help center). The current wording of your question suggests you only want to know why the computational complexity of your code is not what you expect.
– Graham
Nov 20 at 13:47






Welcome to Code Review! We generally provide open-ended feedback about all aspects of your code (see "Do I want feedback about any or all facets of the code?" in the help center). The current wording of your question suggests you only want to know why the computational complexity of your code is not what you expect.
– Graham
Nov 20 at 13:47






1




1




It isn't O(n*n) but Codility only estimates it by runtime. Is there any reason for using Map<Integer, Integer> instead of just int lowerSplitSumValue? You know the array will have same length as int A. Using Map in such case brings no benefits, it is only slower. Maybe that is enough to exceed time limits on task.
– user158037
Nov 20 at 15:28




It isn't O(n*n) but Codility only estimates it by runtime. Is there any reason for using Map<Integer, Integer> instead of just int lowerSplitSumValue? You know the array will have same length as int A. Using Map in such case brings no benefits, it is only slower. Maybe that is enough to exceed time limits on task.
– user158037
Nov 20 at 15:28




1




1




Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles.
– Toby Speight
Nov 21 at 8:17




Welcome to Code Review! The current question title, which states your concerns about the code, is too general to be useful here. Please edit to the site standard, which is for the title to simply state the task accomplished by the code. Please see How to get the best value out of Code Review: Asking Questions for guidance on writing good question titles.
– Toby Speight
Nov 21 at 8:17




2




2




"What is the complexity of my algorithm?" sounds like you don't understand your own code. "*Can I reduce the algorithmic complexity?" would sound more like (part of) a review request. You also should attempt to explain (in your own words) the problem you're solving, rather than just relying on a link.
– Toby Speight
Nov 21 at 8:45






"What is the complexity of my algorithm?" sounds like you don't understand your own code. "*Can I reduce the algorithmic complexity?" would sound more like (part of) a review request. You also should attempt to explain (in your own words) the problem you're solving, rather than just relying on a link.
– Toby Speight
Nov 21 at 8:45






1




1




All I can suggest is simply stating that you and the judge disagree on the complexity (and justify your reasoning), and let the reviewers choose whether to pick up on that. BTW, you should be able to solve this with an algorithm that scales as O(n), with no other containers needed. Think about how the left sum and right sum each change as you move one position along the input.
– Toby Speight
Nov 21 at 8:55




All I can suggest is simply stating that you and the judge disagree on the complexity (and justify your reasoning), and let the reviewers choose whether to pick up on that. BTW, you should be able to solve this with an algorithm that scales as O(n), with no other containers needed. Think about how the left sum and right sum each change as you move one position along the input.
– Toby Speight
Nov 21 at 8:55















active

oldest

votes











Your Answer





StackExchange.ifUsing("editor", function () {
return StackExchange.using("mathjaxEditing", function () {
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
});
});
}, "mathjax-editing");

StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "196"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208071%2fcodility-tape-equilibrium%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Code Review Stack Exchange!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


Use MathJax to format equations. MathJax reference.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f208071%2fcodility-tape-equilibrium%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Quarter-circle Tiles

build a pushdown automaton that recognizes the reverse language of a given pushdown automaton?

Mont Emei