[LintCode] Subarray Sum II

Given an integer array, find a subarray where the sum of numbers is in a given interval. Your code should return the number of possible answers. (The element in the array should be positive)

Example

Given [1,2,3,4] and interval = [1,3], return 4.

Brainstorming:

This problem asks for all possible answers,  which can be O(n^2) in the worst case(all subarrays‘ sum are inside the given interval).  Dynamic programming is not useful most of the time

when a problem asks for all possible answers.  Because the worst case has O(n^2) answers, so the BCR can not be better than O(n^2) as we need to iterate all subarrays to get the

correct answer.

So the optimal solution is O(n^2) runtime, which usually comes at the format of a nested for loop.

Solution 1. O(n^3) runtime, O(1) space

A straightforward solution is to enumerate all possible subarrays in O(n^2) time, then for each subarray, get its sum and check if this sum is in the given interval.

The implementation of this solution is shown as follows.

 1 public class Solution {
 2     /**
 3      * @param A an integer array
 4      * @param start an integer
 5      * @param end an integer
 6      * @return the number of possible answer
 7      */
 8     public int subarraySumII(int[] A, int start, int end) {
 9         if(A == null || A.length == 0 || end < start){
10             return 0;
11         }
12         int cnt = 0;
13         for(int j = 0; j < A.length; j++){
14             for(int i = 0; i <= j; i++){
15                 int sum = subSum(A, i, j);
16                 if(sum >= start && sum <= end){
17                     cnt++;
18                 }
19             }
20         }
21         return cnt;
22     }
23     private int subSum(int[] A, int left, int right){
24         int r = 0;
25         for(int i = left; i <= right; i++){
26             r += A[i];
27         }
28         return r;
29     }
30 }

Solution 2. O(n^2) runtime, O(n) space with prefix sum.

Solution 1‘s runtime is O(n^3), not the optimal O(n^2). Applying the BUD(Bottlenecks, Unnecessary work,

Duplicated work) principle, we know that we are doing duplicated work when getting a subarray‘s sum.

Why?

Each time we fix the start and end indices of a subarray,  it is only one element different from the previously checked subarray. But this solution does not use this

condition. Instead, it calculates a subarray‘s sum from stratch. What can be optimized here is that we use prefix sum and calculate the sum of the first ith elements

for i = 0, 1, ...... n;  This preprocessing step takes O(n) time and O(n) space. When calculating a subarray‘s sum, only a O(1) subtraction is needed , thus making

its runtime to the optimal O(n^2).

This is similiar with the relation between straightforward recursion and dynamic programming. Sacrifice some space for a faster runtime.

 1 public class Solution {
 2     public int subarraySumII(int[] A, int start, int end) {
 3         if(A == null || A.length == 0 || end < start){
 4             return 0;
 5         }
 6         int[] prefixSum = new int[A.length + 1];
 7         prefixSum[0] = 0;
 8         for(int i = 1; i <= A.length; i++){
 9             prefixSum[i] = prefixSum[i - 1] + A[i - 1];
10         }
11         int cnt = 0;
12         for(int i = 0; i < A.length; i++){
13             for(int j = i + 1; j <= A.length; j++){
14                 int diff = prefixSum[j] - prefixSum[i];
15                 if(diff >= start && diff <= end){
16                     cnt++;
17                 }
18             }
19         }
20         return cnt;
21     }
22 }
Solution 3. O(n^2) runtime, O(1) space 

We can further optimize the memory usage from O(n) to O(1). A single integer totalSum is used to keep the current sum of A[0.....j]. Another integer variable sum is used to keep the current sum of A[i.......j].
 1 public class Solution {
 2     public int subarraySumII(int[] A, int start, int end) {
 3         if(A == null || A.length == 0 || end < start){
 4             return 0;
 5         }
 6         int totalSum = 0;
 7         for(int i = 0; i < A.length; i++){
 8             totalSum += A[i];
 9         }
10         int cnt = 0;
11         for(int j = A.length - 1; j >= 0; j--){
12             int sum = totalSum;
13             for(int i = 0; i <= j; i++){
14                 if(i > 0){
15                     sum -= A[i - 1];
16                 }
17                 if(sum >= start && sum <= end){
18                     cnt++;
19                 }
20             }
21             totalSum -= A[j];
22         }
23         return cnt;
24     }
25 }
Related ProblemsSubarray SumSubarray Sum Closest

时间: 2024-10-20 21:28:49

[LintCode] Subarray Sum II的相关文章

Continuous Subarray Sum II(LintCode)

Continuous Subarray Sum II Given an circular integer array (the next element of the last element is the first element), find a continuous subarray in it, where the sum of numbers is the biggest. Your code should return the index of the first number a

[LintCode] Subarray Sum &amp; Subarray Sum II

Subarray Sum Given an integer array, find a subarray where the sum of numbers is zero. Your code should return the index of the first number and the index of the last number. Example Given [-3, 1, 2, -3, 4], return [0, 2] or [1, 3]. 用hashmap来存从nums[0

Lintcode: k Sum II

Given n unique integers, number k (1<=k<=n) and target. Find all possible k integers where their sum is target. Example Given [1,2,3,4], k=2, target=5, [1,4] and [2,3] are possible solutions. 这道题同Combination Sum II 1 public class Solution { 2 /** 3

Continuous Subarray Sum II

Given an circular integer array (the next element of the last element is the first element), find a continuous subarray in it, where the sum of numbers is the biggest. Your code should return the index of the first number and the index of the last nu

LintCode &quot;Continuous Subarray Sum II&quot;

Flip over your mind: in rotated subarray case, we can simply cut the continuous smallest subarray. class Solution { public: /** * @param A an integer array * @return A list of integers includes the index of * the first number and the index of the las

Lintcode: Interval Sum II

Given an integer array in the construct method, implement two methods query(start, end) and modify(index, value): For query(start, end), return the sum from index start to index end in the given array. For modify(index, value), modify the number in t

LintCode: Combination Sum II

C++ DFS 1 class Solution { 2 public: 3 void help(vector<int> &a, int now, int sum, int target, vector<int> &path, vector<vector<int> > &ans, bool last) { 4 if (sum > target) { 5 return ; 6 } 7 if (now >= a.size())

Leetcode: Maximum Size Subarray Sum Equals k

Given an array nums and a target value k, find the maximum length of a subarray that sums to k. If there isn't one, return 0 instead. Example 1: Given nums = [1, -1, 5, -2, 3], k = 3, return 4. (because the subarray [1, -1, 5, -2] sums to 3 and is th

560. Subarray Sum Equals K

Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k. Example 1: Input:nums = [1,1,1], k = 2 Output: 2 Note: The length of the array is in range [1, 20,000]. The range of numbers