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...
java complexity
|
show 6 more comments
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...
java complexity
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'tO(n*n)
but Codility only estimates it by runtime. Is there any reason for usingMap<Integer, Integer>
instead of justint lowerSplitSumValue
? You know the array will have same length asint 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
|
show 6 more comments
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...
java complexity
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
java complexity
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'tO(n*n)
but Codility only estimates it by runtime. Is there any reason for usingMap<Integer, Integer>
instead of justint lowerSplitSumValue
? You know the array will have same length asint 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
|
show 6 more comments
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'tO(n*n)
but Codility only estimates it by runtime. Is there any reason for usingMap<Integer, Integer>
instead of justint lowerSplitSumValue
? You know the array will have same length asint 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
|
show 6 more comments
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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 usingMap<Integer, Integer>
instead of justint lowerSplitSumValue
? You know the array will have same length asint 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