问题
Here's my Task Description:
A zero-indexed array A consisting of N integers is given.
An equilibrium index of this array is any integer P such that 0 ≤ P < N and the sum of elements of lower indices is equal to the sum of elements of higher indices, i.e. A[0] + A1 + ... + A[P−1] = A[P+1] + ... + A[N−2] + A[N−1].
Sum of zero elements is assumed to be equal to 0. This can happen if P = 0 or if P = N−1. For example, consider the following array A consisting of N = 8 elements:
A[0] = -1
A[1] = 3
A[2] = -4
A[3] = 5
A[4] = 1
A[5] = -6
A[6] = 2
A[7] = 1
P = 1 is an equilibrium index of this array, because:
• A[0] = −1 = A[2] + A[3] + A[4] + A[5] + A[6] + A[7]
P = 3 is an equilibrium index of this array, because:
• A[0] + A[1] + A[2] = −2 = A[4] + A[5] + A[6] + A[7]
P = 7 is also an equilibrium index, because:
• A[0] + A[1] + A[2] + A[3] + A[4] + A[5] + A[6] = 0
and there are no elements with indices greater than 7. P = 8 is not an equilibrium index, because it does not fulfill the condition 0 ≤ P < N.
Write a function: int solution(NSMutableArray *A); that, given a zero-indexed array A consisting of N integers, returns any of its equilibrium indices.
The function should return −1 if no equilibrium index exists. For example, given array A shown above, the function may return 1, 3 or 7, as explained above.
Assume that: • N is an integer within the range [0..100,000]; • each element of array A is an integer within the range [−2,147,483,648..2,147,483,647].
Complexity: • expected worst-case time complexity is O(N); • expected worst-case space complexity is O(N), beyond input storage (not counting the storage required for input arguments).
Elements of input arrays can be modified.
Here's my Solution for the problem in Objective C:
-(int)solution:(NSArray *) A{
for (int i=0; i<A.count; i++) {
NSUInteger backwardsTotal = 0;
if (i > 0) {
for (int k=0; k<i; k++) {
NSNumber *kValue = A[k];
backwardsTotal += kValue.intValue;
}
}
NSUInteger forwardTotal = 0;
for (int j=i+1; j<A.count; j++) {
NSNumber *jValue = A[j];
forwardTotal += jValue.intValue;
}
if (backwardsTotal == forwardTotal) {
return i;
}
}
return -1;
}
How can i optimise this solution?
Changes made to the method as per @Nikki comments:
-(int)solution:(NSArray *) A{
NSUInteger a = 0, b = 0;
for (int i=0; i<A.count; i++) {
NSNumber *iValue = A[i];
b += iValue.intValue;
}
NSLog(@"Total: b: %ld", b);
for (int k=0; k<A.count; k++) {
NSNumber *kValue = A[k];
b -= kValue.intValue;
NSLog(@"b: %ld", b);
NSLog(@"a: %ld", a);
if (a == b)
return k;
a += kValue.intValue;
}
return -1;
}
I am testing the above code as follows:
// NSArray *array = @[@"-3", @"0", @"3"];
NSArray *array = @[@"-2", @"4", @"-5", @"6", @"1", @"-6", @"2", @"1"];
NSUInteger one = [self solution:array];
NSLog(@"one: %ld", one);//returns 7
The solution seems to work better. But still, it is not perfect and uses O(N**2) time complexity. And also there are Timeout errors in other Performance tests.
Screenshots below:
Can this be still optimized?
回答1:
Your current solution is O(n^2) operations (You sum the whole array n times).
You could have just 2 variables at any point, a and b, setting a to zero and b to the sum of the array. Afterwards, iterate over all of the indices. When iterating over index i, first do b -= arr[i]. Then, if a==b, return i. Then do a += arr[i]. That is O(n) operations, much more efficient.
回答2:
How about this, hope it works for ya..
int equi(int arr[], int n) {
if (n==0) return -1;
long long sum = 0;
int i;
for(i=0;i<n;i++) sum+=(long long) arr[i];
long long sum_left = 0;
for(i=0;i<n;i++) {
long long sum_right = sum - sum_left - (long long) arr[i];
if (sum_left == sum_right) return i;
sum_left += (long long) arr[i];
}
return -1;
}
回答3:
Official C solution from Codility
http://blog.codility.com/2011/03/solutions-for-task-equi.html
int equi(int arr[], int n) {
if (n==0) return -1;
long long sum = 0;
int i;
for(i=0;i<n;i++) sum+=(long long) arr[i];
long long sum_left = 0;
for(i=0;i<n;i++) {
long long sum_right = sum - sum_left - (long long) arr[i];
if (sum_left == sum_right) return i;
sum_left += (long long) arr[i];
}
return -1;
}
Two points to note:
long long
is used to prevent overflow. This is enough because of the minimum size guarantees mentioned at+ https://stackoverflow.com/a/37124098/895245 together with Codility's input- take care of the
n==0
special case
Other languages:
- Java https://stackoverflow.com/questions/21176777/codility-equilibrium-index-sample-test-my-stab-at-it
- C# faster implementation of sum ( for Codility test )
- Python Index in an array such that its prefix sum equals its suffix sum - best solution
来源:https://stackoverflow.com/questions/32346389/algorithm-code-optimization-find-the-equilibirum-find-an-index-in-an-array-suc