找到sum k数组的所有连续子序列

时间:2015-08-12 19:32:39

标签: arrays dynamic-programming subsequence contiguous

示例:

数组如下:-4 -10 -15 - 20 100 -67 47 20k = 51

预期产出:

-4 -10 -15 - 20 100

-4 -10 -15 - 20 100 -67 47 20

用O(n ^ 2)试验蛮力溶液。任何人都可以建议一个更好的解决方案吗?

1 个答案:

答案 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