简体   繁体   English

对于小于和等于O(n2)的负数和正数,子数组总和等于k

[英]Subarray sum equal to k for negative and positive numbers in less than O(n2)

I can search for subarrays with sum eqaul to k for positive numbers but the below code fails for negative numbers in arrays. 我可以搜索总和等于k的子数组来获取正数,但是下面的代码无法搜索数组中的负数。 Is there an algorithm for finding subarrays with a given sum for negative and positive numbers in an array ? 是否存在一种算法,用于查找数组中负数和正数具有给定总和的子数组?

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];
        }

    }
}

For example, {10, 2, -2, -20, 10}, find subarray with sum -10 in this array. 例如,{10,2,-2,-20,10},在此数组中找到总和为-10的子数组。 Subarray in this case would be {-20, 10}. 在这种情况下,子数组将为{-20,10}。

O(N^2) solution O(N^2)

For each index i precalculate the sum of subarray from 0 to i , inclusively. 对于每个索引, i预先计算子数组的总和,范围从0i Then to find sum of any subarray (i, j) you can just calculate sum[j] - sum[i] + arr[i] . 然后,要找到任何子数组(i, j) sum[j] - sum[i] + arr[i] (i, j)您只需计算sum[j] - sum[i] + arr[i]

  public static void subArraySum(int[] arr, int target) {
    if (arr.length == 0) return;

    int n = arr.length;
    int[] sum = new int[n];
    sum[0] = arr[0];
    for (int i = 1; i < n; ++i) {
        sum[i] = sum[i - 1] + arr[i];
    }

    for (int i = 0; i < n; ++i)
      for (int j = i; j < n; ++j)
        if (sum[j] - sum[i] + arr[i] == target) {
            System.out.println(i + " " + j);
        }
  }

Faster solution 更快的解决方案

You can find subarray faster if you will store the sums in the map and then query this map for the required sum. 如果将总和存储在地图中,然后在该地图中查询所需的总和,则可以更快地找到子数组。

 public static void subArraySum(int[] arr, int target) {
  if (arr.length == 0) return;

  int n = arr.length;
  int[] sum = new int[n];
  sum[0] = arr[0];
  for (int i = 1; i < n; ++i) {
      sum[i] = sum[i - 1] + arr[i];
  }

  Map<Integer, Integer> map = new TreeMap<>();
  for (int i = 0; i < n; ++i) {
      if (sum[i] == target) {
          System.out.println(0 + " " + i);
      }

      int requiredSum = sum[i] - target;
      if (map.containsKey(requiredSum)) {
          int startIndex = map.get(requiredSum) + 1;
          System.out.println(startIndex + " " + i);
      }
      map.put(sum[i], i);
  }
}

This solution is O(N*logN) , but you can make it faster if you will use HashMap instead of TreeMap ( O(N) if you assume that HashMap operations complexity is constant). 此解决方案是O(N*logN) ,但是如果您将使用HashMap而不是TreeMap,则可以使其更快O(N)如果您假设HashMap操作复杂性是恒定的,则为O(N) )。

Note that this solution will not print all possible pairs. 请注意,此解决方案不会打印所有可能的对。 If you need to find all subarrays with given sum you need to have Map<Integer, Array<Integer>> instead of Map<Integer, Integer> and store all indexes with given sum. 如果需要查找具有给定总和的所有子Map<Integer, Array<Integer>>需要具有Map<Integer, Array<Integer>>而不是Map<Integer, Integer>并存储具有给定总和的所有索引。

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

相关问题 计算小于或等于N的两个数字的对数,以使对数的数字总和为质数 - Count number of pairs of two numbers less than or equal to N such that Sum of the digits of numbers of pair is Prime 使元素之和小于或等于 k 的方式总数 - Total number of ways such that the sum of elements is less than or equal to k 小数负数和正数之和 - Decimal negative and positive numbers sum 最大和子数组O(n)不是Kadane的 - Maximum Sum Subarray O(n) not Kadane's 从排序数组中查找小于O(n)的唯一数字 - Finding unique numbers from sorted array in less than O(n) 数组,正负数的数量必须相等 - Array, quantity of positive and negative numbers must be equal 在 O(Log N) 中获取循环排序数组中所有正数的总和 - Get the Sum of all positive numbers in a Circularly ordered array in O(Log N) 编写一个 while 循环,打印所有可被 10 整除且小于给定数 n 的正数 - Write a while loop that prints all positive numbers that are divisible by 10 and less than a given number n 给定数字n,我们必须找出小于或等于n的正好有3个除数的数字 - given a number n , we have to find out such numbers that are less than or equal to n, that have exactly 3 divisors 查找最长子数组,其和可被O(N)复杂度除以3 - Find longest subarray whose sum divisible by 3 with O(N) Complexity
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM