Given array : 8 3 5 2 10 6 7 9 5 2
So the o/p will be Yes.
as:{8,3,5} {10,6} {9,5,2}他们都有相同的总和值,即16。
But for this array : 1 4 9 6 2 12
o/p will be No.
as:没有连续的幻灯片具有相同的总和值
我正在考虑使用 SubSetSum算法/ Kadane最大子阵列算法,但后来我最终因为所有算法都需要预定义的目标总和。 但是这里我们不知道目标总和
答案 0 :(得分:1)
如果给出了所需的总和,并且所有子阵列都应该是连续的,那么可以在O(n)
中轻松完成。
在数组上运行循环并维护切片(left
和right
索引)和currentSum
的边界。
从第一个元素开始为0.边界将是[0,0](为简单起见,我们包括右边)。然后在一个循环中你有三个条件。
转换为代码
public static void main(String[] args) {
int givenSum = 16;
int[] a = new int[] {8, 3, 5, 2, 10, 6, 7, 9, 5, 2};
// boundaries of slice
int left = 0; // defines position of slice
int right = 0; // exclusive
int currentSum = 0;
while (right < a.length) {
if (currentSum < givenSum) { // sum is not enough, add from the right
currentSum += a[right];
right++;
}
if (currentSum > givenSum) { // sum exceeds given, remove from the left
currentSum -= a[left];
left++;
}
if (currentSum == givenSum) { // boundaries of given sum found, print it
System.out.println(Arrays.toString(Arrays.copyOfRange(a, left, right)));
// remove the left element, so we can process next sums
currentSum -= a[left];
left++;
}
}
}
对于你的情况,它打印4个切片,产生总和16
[8, 3, 5]
[10, 6]
[7, 9]
[9, 5, 2]
编辑:
由于OP澄清,没有给定的总和,目标是检查是否存在至少两个不同的连续子阵列,产生相等的总和。
最直接的算法是生成所有可能的总和并检查是否存在重复
int[] a = new int[] {1, 4, 9, 6, 2, 12};
HashSet<Integer> sums = new HashSet<>();
int numOfSums = 0;
for (int left = 0; left < a.length - 1; left++) {
for (int right = left; right < a.length; right++) {
// sum from left to right
int sum = 0;
for (int k = left; k <= right; k++) {
sum += a[k];
}
numOfSums++;
sums.add(sum);
}
}
System.out.println(sums.size() == numOfSums);
这是O(n^3)
的复杂性,不是一个好的,但有效。
提示:可以探索一个技巧来将其提升到O(n^2)
,你不需要计算每对切片的总和!
答案 1 :(得分:0)
您可以通过以下方式执行此操作
答案 2 :(得分:0)
使用动态编程查找数组的所有子和,然后找到具有相同和的子数组。复杂性应该是O(n2)。
void subsum(int n, int* arr, int** sum) {
for (int i = 0; i < n; ++i) {
sum[i][i] = arr[i];
}
for (int l = 2; l <= n; ++l) {
for (int i = 0; i < n - l + 1; ++i) {
sum[i][i + l - 1] = sum[i][i + l - 2] + arr[i + l -1];
}
}
}