Using a map to search for a subarray with a given sum (with negative numbers)

Consider the following task statement:

Given an unsorted array of integers, find the subarray that is added to the given number. If there are multiple subarrays with the sum as the given number, print any of them.

Examples:

Input: arr[] = {1, 4, 20, 3, 10, 5}, sum = 33
Ouptut: Sum found between indexes 2 and 4

Input: arr[] = {10, 2, -2, -20, 10}, sum = -10
Ouptut: Sum found between indexes 0 to 3

Input: arr[] = {-10, 0, 2, -2, -20, 10}, sum = 20
Ouptut: No subarray with given sum exists

The following linear temporary solution was proposed on this site using a map to store the sums of the current subsets as an iteration algorithm through an array:

// Function to print subarray with sum as given sum
void subArraySum(int arr[], int n, int sum)
{
    // create an empty map
    unordered_map<int, int> map;

    // Maintains sum of elements so far
    int curr_sum = 0;

    for (int i = 0; i < n; i++)
    {
        // add current element to curr_sum
        curr_sum = curr_sum + arr[i];

        // if curr_sum is equal to target sum
        // we found a subarray starting from index 0
        // and ending at index i
        if (curr_sum == sum)
        {
            cout << "Sum found between indexes "
                 << 0 << " to " << i << endl;
            return;
        }

        // If curr_sum - sum already exists in map
        // we have found a subarray with target sum
        if (map.find(curr_sum - sum) != map.end())
        {
            cout << "Sum found between indexes "
                 << map[curr_sum - sum] + 1
                 << " to " << i << endl;
            return;
        }

        map[curr_sum] = i;
    }

    // If we reach here, then no subarray exists
    cout << "No subarray with given sum exists";
}
// Driver program to test above function
int main()
{
    int arr[] = {10, 2, -2, -20, 10};
    int n = sizeof(arr)/sizeof(arr[0]);
    int sum = -10;

    subArraySum(arr, n, sum);

    return 0;
}

In the test case, which is indicated in the message, the second if statement checks if current_sum-sum will be present. Instead, the sum is found and printed in the first if statement. So here are a few confusions. :

1: What is the purpose of current_sum-suma map search ?

2: if, ?

+4
3
    curr_sum = curr_sum + arr[i];

:

curr_sum ( arr [i]), arr [0]

if (curr_sum == sum)
{
    cout << "Sum found between indexes "
         << 0 << " to " << i << endl;
    return;
}

:

if , curr_sum . , curr_sum , arr [0].

, 2 4, .

Input: arr[] = {1, 4, 20, 3, 10, 5}, sum = 33
Ouptut: Sum found between indexes 2 and 4

= 4, curr_sum 38. 1 4 out (arr [0] arr [1], ), 33.

    if (map.find(curr_sum - sum) != map.end())
    {
        cout << "Sum found between indexes "
             << map[curr_sum - sum] + 1
             << " to " << i << endl;
        return;
    }

    map[curr_sum] = i;

.

 map[curr_sum] = i;

map (i) ( arr 0 i) . , :

  • [1] = 0
  • [5] = 1
  • map [25] = 2
  • map [28] = 3
  • [38] = 4

:

    map.find(curr_sum - sum)

, (curr_sum - sum).

, = 4, curr_sum 38, , , 33. arr [0,2], 33. , map.find(curr_sum-sum) = > map.find(38-33) , [5] = 1.

, .

+8

:

  • 0 n - , . cur_sum - , , .
  • m n - , . , m , ( 0 n) ( 0 m) - , . , cur_sum - sum - , .

    - 33 {1, 4, 20, 3, 10, 5}. n==4 cur_sum of 38. 5 .

+7

, . , arr [start] currSum 1, currSum > sum.

In case there can be negative integers in the array, this method can be used using a map.

Try this example to understand the solution:

-5, 2, 10, 20, 3, 8

sum = 33

Answer: The sum found between the indices from 2 to 4

0
source

Source: https://habr.com/ru/post/1653622/


All Articles