示例:
数组如下:-4 -10 -15 - 20 100 -67 47 20
和
k = 51
预期产出:
-4 -10 -15 - 20 100
-4 -10 -15 - 20 100 -67 47 20
用O(n ^ 2)试验蛮力溶液。任何人都可以建议一个更好的解决方案吗?
答案 0 :(得分:0)
我们可以在O(nlogn)
中完成。
我们先解决一个简单的问题:
For an array, find two elements in the array which sum is k.
所以,我们可以做到:
algo_1
pre = []
for(int i = 0; i < array.length; i++) {
if pre.elementValueIs(k - array[i])
output()
pre.add(array[i])
}
通过BST(Java.util.Map,C ++地图,Python dict)或二进制搜索,我们可以pre.elementValueIs
中的O(logn)
因此,在摘要中,我们可以获得O(nlogn)
算法。
对于你的问题,我们制作另一个新的数组s [],其中
s[i] = a[i] + a[i - 1] + ... + a[0]
所以如果a[p] + a[p + 1] ... + a[q] = k(p<=q)
,s[q] - s[p - 1]
= k。
通过这种方式,我们可以通过algo_1
解决您的问题。
我为您编写了一个Java代码,您可以调试它以获取更多详细信息:
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
/**
* Created by Sayakiss on 8/13/15.
*/
public class SubSum {
static class SumArray {
private int[] sumArray;
public SumArray(int[] inputArray) {
sumArray = new int[inputArray.length + 1];
sumArray[0] = 0;
for(int i = 0; i < inputArray.length; i++) {
sumArray[i + 1] = inputArray[i] + sumArray[i];
}
}
//get input sum(array[i]) (begin<=i<=end)
public int getSum(int begin, int end) {
return sumArray[end + 1] - sumArray[begin];
}
}
static void printResult(int[] array, int begin, int end) {
for(int i = begin; i<= end; i++) {
System.out.print(array[i]);
if (i != end) {
System.out.print(", ");
}
}
System.out.println();
}
public static void subSum(int[] inputArray, int k) {
HashMap<Integer, List<Integer>> map = new HashMap<>();//sum(a[0..i]) = key
List<Integer> list = new ArrayList<>();
list.add(0);
map.put(0, list);
SumArray sumArray = new SumArray(inputArray);
for(int i = 0; i < inputArray.length; i++) {
int sum = sumArray.getSum(0, i);
List<Integer> beginIndexList = map.get(k - sum);
if (beginIndexList != null) {
for(int beginIndex : beginIndexList)
printResult(inputArray, beginIndex, i);
}
List<Integer> integerList = map.get(sum);
if (integerList == null) {
integerList = new ArrayList<>();
map.put(sum, integerList);
}
integerList.add(i);
}
}
public static void main(String args[]) {
subSum(new int[]{-4, -10, -15, -20, 100, -67, 47, 20}, 51);
}
}
如果你运行我的main函数,你将获得输出(与测试用例相同):
-4, -10, -15, -20, 100
-4, -10, -15, -20, 100, -67, 47, 20