繁体   English   中英

如何在 O(n) 时间复杂度中找到总和为 k 的所有子数组?

[英]How to find all subarrays with sum k in O(n) time complexity?

我可以使用以下代码搜索总和为 k 的子数组:

public static void subarraySum(int[] arr, int sum) {

    int start=0;
    int currSum=arr[0];

    for(int i = 1;i<=arr.length;i++) {
        while(currSum>sum ) {
            currSum-=arr[start];
            start++;
        }
        if(currSum==sum) {
            System.out.println(start + " " + (i-1) + " index");
            start=i;
            currSum=0;
        }
        if(i<arr.length) {
            currSum +=arr[i];
        }

    }

这适用于像 {15,2,4,8,9,5,10,23} 这样的数组。 为此输出将是 2 个子数组 {2,4,9,8} 和 {23}。

但是,对于像 {1,5,2,5,1,3} 这样的数组,这只会给我输出 1 个子数组,但是有 2 个子数组的总和为 7,分别是 {5,2} 和 {2,5}。 关于如何调整上述代码以在第二个数组中给出正确答案的任何建议?

算法并不复杂,我会说明思路,实现留给大家去尝试。

你需要有两个索引i , j 让它们都从第一个元素开始。 现在取它们之间的子数组(最初因为它们都在同一个地方没有子数组)并执行以下测试:

  • 如果它的总和等于您的目标,则添加当前子数组

  • 如果总和小于您的目标,则将j向右移动以再包含一个元素并再次进行测试

  • 如果总和大于您的目标,则将i向右移动以从子数组中删除第一个元素并再次进行测试。

最后,您将拥有总和等于您的目标的所有子数组。

请注意,此解决方案仅适用于正数

是的,我太慢了。 当我解决这个问题以给出代码时,我们有一个正确的算法答案。 +1 来自我,我也可以选择我的代码解决方案(我很多次之前在采访中遇到过这个问题)

public static List<int[]> subarraySum(int[] arr, int sum) {
    List<int[]> res = new ArrayList<>();
    int[] tmp;
    int start = 0;  // inclusive
    int end = 0;    // exclusive
    int currSum = 0;

    do {
        if (end == arr.length && currSum < sum)
            break;
        if (currSum > sum)
            currSum -= arr[start++];
        else if (currSum < sum)
            currSum += arr[end++];
        else if (currSum == sum) {
            res.add(tmp = new int[end - start]);
            System.arraycopy(arr, start, tmp, 0, tmp.length);
            currSum -= arr[start];
            start++;
        }
    } while (start <= arr.length && end <= arr.length);

    return res;
}

它看起来是正确的,但我只在几种情况下测试了这个解决方案。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM