Given an input array find all subarrays with given sum K

前端 未结 9 1219
梦如初夏
梦如初夏 2020-12-23 10:03

Given an input array we can find a single sub-array which sums to K (given) in linear time, by keeping track of sum found so far and the start position. If the current sum b

相关标签:
9条回答
  • 2020-12-23 10:31

    This problem is very similar to the combination problem solved here: http://introcs.cs.princeton.edu/java/23recursion/Combinations.java.html

    Here is my solution:

    public static void main(String[] args) {
        int [] input = {-10, 0, 5, 10, 15, 20, 30};
        int expectedSum = 20;
    
        combination(new SumObj(new int[0]), new SumObj(input), expectedSum);
    }
    
    private static void combination(SumObj prefixSumObj, SumObj remainingSumObj, int expectedSum){
        if(prefixSumObj.getSum() == expectedSum){
            System.out.println(Arrays.toString(prefixSumObj.getElements()));
        } 
    
        for(int i=0; i< remainingSumObj.getElements().length ; i++){
            // prepare new prefix
            int [] newPrefixSumInput = new int[prefixSumObj.getElements().length + 1];
            System.arraycopy(prefixSumObj.getElements(), 0, newPrefixSumInput, 0, prefixSumObj.getElements().length);
            newPrefixSumInput[prefixSumObj.getElements().length] = remainingSumObj.getElements()[i];
            SumObj newPrefixSumObj = new SumObj(newPrefixSumInput);
    
            // prepare new remaining
            int [] newRemainingSumInput = new int[remainingSumObj.getElements().length - i - 1];            
            System.arraycopy(remainingSumObj.getElements(), i+1, newRemainingSumInput, 0, remainingSumObj.getElements().length - i - 1);
            SumObj newRemainingSumObj = new SumObj(newRemainingSumInput);
    
            combination(newPrefixSumObj, newRemainingSumObj, expectedSum);
        }
    }
    
    private static class SumObj {
        private int[] elements;
        private int sum;
    
        public SumObj(int[] elements) {
            this.elements = elements;
            this.sum = computeSum();
        }
    
        public int[] getElements() {
            return elements;
        }
    
        public int getSum() {
            return sum;
        }
    
        private int computeSum(){
            int tempSum = 0;
            for(int i=0; i< elements.length; i++){
                tempSum += elements[i];
            }
            return tempSum;
        }
    }
    
    0 讨论(0)
  • 2020-12-23 10:41

    Try this code this can work for you:

    private static void printSubArrayOfRequiredSum(int[] array, int requiredSum) {
            for (int i = 0; i < array.length; i++) {
                String str = "[ ";
                int sum = 0;
                for (int j = i; j < array.length; j++) {
                    sum = sum + array[j];
                    str = str + array[j] + ", ";
                    if (sum == requiredSum) {
                        System.out.println(" sum : " + sum + " array : " + str
                                + "]");
                        str = "[ ";
                        sum = 0;
                    }
                }
            }
        }
    

    Use this method like :

     int array[] = { 3, 5, 6, 9, 14, 8, 2, 12, 7, 7 };
     printSubArrayOfRequiredSum(array, 14);
    

    Output :

    sum : 14 array : [ 3, 5, 6, ]
    sum : 14 array : [ 14, ]
    sum : 14 array : [ 2, 12, ]
    sum : 14 array : [ 7, 7, ]
    
    0 讨论(0)
  • 2020-12-23 10:41

    Quadratic Time: O(n2) in worst case.

    private static void findSubArray(int[] is, int N) {
        System.out.println("Continuous sub array of " + Arrays.toString(is) + " whose sum is " + N + " is ");
        List<Integer> arry = new ArrayList<>(is.length);
        for (int i = 0; i < is.length; i++) {
            int tempI = is[i];
            arry.add(tempI);
            for (int j = i + 1; j < is.length; j++) {
                if (tempI + is[j] == N) {
                    arry.add(is[j]);
                    System.out.println(arry);
    
                } else if (tempI + is[j] < N) {
                    arry.add(is[j]);
                    tempI = tempI + is[j];
                } else {
                    arry.clear();
                    break;
                }
            }
        }
    
    }
    public static void main(String[] args) {
        findSubArray(new int[] { 42, 15, 12, 8, 6, 32 }, 26);
    
        findSubArray(new int[] { 12, 5, 31, 13, 21, 8 }, 49);
    
        findSubArray(new int[] { 15, 51, 7, 81, 5, 11, 25 }, 41);
    }
    
    0 讨论(0)
  • 2020-12-23 10:43

    Solution as given by @Evgeny Kluev coded in Java with a little explanation.

    public static void main(String[] args) {
        int[] INPUT = {5, 6, 1, -2, -4, 3, 1, 5};
        printSubarrays(INPUT, 5);
    }
    
    private static void printSubarrays(int[] input, int k) {
        Map<Integer, List<Integer>> map = new HashMap<Integer, List<Integer>>();
        List<Integer> initial = new ArrayList<Integer>();
        initial.add(-1);
        map.put(0, initial);
        int preSum = 0;
    
        // Loop across all elements of the array
        for(int i=0; i< input.length; i++) {
            preSum += input[i];
            // If point where sum = (preSum - k) is present, it means that between that 
            // point and this, the sum has to equal k
            if(map.containsKey(preSum - k)) {   // Subarray found 
                List<Integer> startIndices = map.get(preSum - k);
                for(int start : startIndices) {
                    System.out.println("Start: "+ (start+1)+ "\tEnd: "+ i);
                }
            }
    
            List<Integer> newStart = new ArrayList<Integer>();
            if(map.containsKey(preSum)) { 
                newStart = map.get(preSum);
            }
            newStart.add(i);
            map.put(preSum, newStart);
        }
    }
    
    0 讨论(0)
  • 2020-12-23 10:43

    Python code with O(n) space and time complexity

    from collections import *
    k,presum,arr = 5,0,[1,-1,5,-5,5]
    start_indices = defaultdict(list)
    start_indices[0] = [-1] #this is required for subarrays starting from 0th index
      
    for idx,ele in enumerate(arr):
        presum += ele
        for i in start_indices[presum-k]:
            print(arr[i+1:idx+1])
        start_indices[presum] += [idx]
    
    0 讨论(0)
  • 2020-12-23 10:50

    Solution as given by @Evgeny Kluev coded in c++

    #include<bits/stdc++.h>
    using namespace std;
    int c=0;
    // Function to print subarray with sum as given sum
    void subArraySum(int arr[], int n, int k)
    {
       map<int,vector<int>>m1;
       m1[0].push_back(-1);
       int curr_sum=0;
       for(int i=0;i<n;i++){
           curr_sum=curr_sum+arr[i];
           if(m1.find(curr_sum-k)!=m1.end()){
               vector<int>a=m1[curr_sum-k];
               c+=m1[curr_sum-k].size();
               for(int j=0;j<a.size();j++){  // printing all indexes with sum=k
                  cout<<a[j]+1<<" "<<i<<endl;
                }
            }
            m1[curr_sum].push_back(i);
        }  
     }
    int main()
    {
       int arr[] =  {10,2,0,10,0,10};
       int n = sizeof(arr)/sizeof(arr[0]);
       int sum = 10;
       subArraySum(arr, n, sum);
       cout<<c<<endl; //count of subarrays with given sum
       return 0;
    }
    
    0 讨论(0)
提交回复
热议问题