假设你有一个整数数组。找到所有位置p(如果它们存在),以便从0到p的元素之和等于从p + 1到数组末尾的元素之和。
Java是答案的首选,但任何其他语言都没问题,谢谢。
答案 0 :(得分:0)
解决这个问题的一种方法是注意,从0到p的元素之和必须完全等于所有元素的总和除以2.
这是因为两个部分(0到p部分和p + 1到结尾部分)必须相等,并且两个部分加在一起构成整个数组。
对于此解决方案,您只需执行两次传递。 在第一遍中,您总结了数组中的所有元素。
在第二遍中,您正在查找每个索引,使得到该索引的数组总和等于总和的一半。
在伪代码中:
total_amount = sum(array)
current_partial_sum = 0
for i in index of array:
current_partial_sum += array[i];
if (current_partial_sum == total_amount/2) {
add i to the solution
}
}
答案 1 :(得分:0)
如果你可以假设所有整数都是正数,那么它会大大简化问题。您可以遍历数组一次以找到总和,然后再次行走,直到您(可能)找到两个总和相等的点。这样做的原因是向左或向右移动将总是增加/减少总和。但是,可能存在零,这些也需要考虑。
public List<Integer> getPosition(int[] array) {
List<Integer> result = new ArrayList<Integer>();
// first walk through the array to determine the total sum
// cost is O(N)
int sum = 0;
for (int i=0; i < array.length; ++i) {
sum += array[i];
}
// next walk through the array again, checking at each step
// if the running sum be half the total
// cost is O(N)
int runningSum = 0;
int position = -1;
for (int i=0; i < array.length; ++i) {
runningSum += array[i];
// if position found, then break
if (runningSum == sum / 2) {
position = i;
break;
}
}
result.add(position);
// there may be zeroes to the right of the pivot
// if so, they are also valid points and must be added
if (position != -1) {
int i = position + 1;
while (array[i] == 0) {
result.add(i);
++i;
}
}
return result;
}
int[] myArray = new int[] {1, 3, 2, 8, 5, 1, 0, 0, 0, 9, 5, 6};
List<Integer> position = getPosition(myArray);
<强>输出:强>
[5, 6, 7, 8]
这个答案有意义,因为0 - 5
的总和为20
,而6 - 11
的总和为20
。此外,我们也可以从6
,7
或8
开始,并将数组分成两个20的总和。
[1, 3, 2, 8, 5, 1, 0, 0, 0, 9, 5, 6]
^ this value of p divides the array into two sums of 20
^ ^ ^ but any of these values also divide the array