Facebook Pixel

2395. Find Subarrays With Equal Sum

EasyArrayHash Table
Leetcode Link

Problem Description

You are given a 0-indexed integer array nums. Your task is to determine whether there exist two subarrays, each of length 2, that have equal sums. These two subarrays must start at different indices in the array.

A subarray is defined as a contiguous non-empty sequence of elements within an array. In this problem, you're specifically looking for subarrays of exactly 2 consecutive elements.

For example:

  • If nums = [1, 2, 3, 4], the subarrays of length 2 would be [1, 2], [2, 3], and [3, 4]
  • You need to check if any two of these subarrays have the same sum
  • The subarrays [1, 2] and [2, 3] have sums 3 and 5 respectively (different sums)
  • If any two subarrays had the same sum, you would return true

The function should return true if such a pair of subarrays exists, and false otherwise.

The key insight is that you need to find at least two different pairs of adjacent elements in the array that sum to the same value. Since each subarray of length 2 consists of two adjacent elements, you're essentially looking for duplicate sums among all possible pairs of consecutive elements.

Quick Interview Experience
Help others by sharing your interview experience
Have you seen this problem before?

Intuition

The problem asks us to find if there are two subarrays of length 2 with equal sums. Since each subarray of length 2 is just a pair of adjacent elements, we're essentially looking for duplicate sums among all consecutive pairs.

Think about it this way: if we have an array like [4, 2, 4, 1, 3], we can calculate the sum of each consecutive pair:

  • 4 + 2 = 6
  • 2 + 4 = 6
  • 4 + 1 = 5
  • 1 + 3 = 4

Notice that the first two pairs both sum to 6, so we have found our answer.

The key realization is that we don't need to store the actual subarrays or their indices - we only care about whether we've seen a particular sum before. This naturally leads us to use a hash table (set) approach:

  1. As we iterate through the array, we calculate the sum of each consecutive pair
  2. Before adding a new sum to our set, we check if it already exists
  3. If it exists, we've found two different subarrays with the same sum
  4. If it doesn't exist, we add it to the set and continue

This approach works because:

  • We process pairs from left to right, so when we encounter a sum we've seen before, we know it must be from a different starting index
  • We only need to detect the first duplicate sum to return true
  • Using a set gives us O(1) lookup time to check if we've seen a sum before

The beauty of this solution is its simplicity - we transform the problem from "finding equal subarrays" to "finding duplicate sums", which is a much simpler problem to solve efficiently.

Solution Approach

The solution uses a hash table (set) to track the sums we've encountered while iterating through consecutive pairs of elements.

Here's the step-by-step implementation:

  1. Initialize a hash set: Create an empty set called vis (visited) to store the sums of consecutive pairs we've seen so far.

  2. Iterate through consecutive pairs: Use the pairwise function to iterate through all consecutive pairs (a, b) in the array. The pairwise function generates tuples of adjacent elements: for array [1, 2, 3, 4], it yields (1, 2), (2, 3), (3, 4).

  3. Calculate and check the sum: For each pair (a, b):

    • Calculate the sum x = a + b
    • Check if this sum already exists in the vis set
    • If it exists, we've found two different subarrays with equal sums, so return True
    • If it doesn't exist, add this sum to the vis set
  4. Return false if no duplicates found: If we complete the iteration without finding any duplicate sums, return False.

Example walkthrough with nums = [4, 2, 4, 1]:

  • First pair (4, 2): sum = 6, vis is empty, add 6 to vis = {6}
  • Second pair (2, 4): sum = 6, 6 is already in vis, return True

Time Complexity: O(n) where n is the length of the array, as we iterate through the array once.

Space Complexity: O(n) in the worst case where all sums are unique and we store n-1 different sums in the hash set.

The use of the walrus operator := in if (x := a + b) in vis: is a Python optimization that assigns the sum to variable x while simultaneously checking if it exists in the set, making the code more concise.

Ready to land your dream job?

Unlock your dream job with a 5-minute evaluator for a personalized learning plan!

Start Evaluator

Example Walkthrough

Let's walk through the solution with nums = [3, 5, 4, 1, 4]:

Step 1: Initialize

  • Create an empty set vis = {} to track sums we've seen

Step 2: Process consecutive pairs

Iteration 1: Pair (3, 5)

  • Calculate sum: 3 + 5 = 8
  • Check if 8 is in vis: No
  • Add 8 to vis: vis = {8}
  • Continue

Iteration 2: Pair (5, 4)

  • Calculate sum: 5 + 4 = 9
  • Check if 9 is in vis: No
  • Add 9 to vis: vis = {8, 9}
  • Continue

Iteration 3: Pair (4, 1)

  • Calculate sum: 4 + 1 = 5
  • Check if 5 is in vis: No
  • Add 5 to vis: vis = {8, 9, 5}
  • Continue

Iteration 4: Pair (1, 4)

  • Calculate sum: 1 + 4 = 5
  • Check if 5 is in vis: Yes! (we added it in iteration 3)
  • We found two subarrays with equal sums:
    • Subarray [4, 1] starting at index 2 has sum 5
    • Subarray [1, 4] starting at index 3 has sum 5
  • Return True

The algorithm successfully identifies that two different subarrays of length 2 have the same sum (5), so it returns True.

Solution Implementation

1class Solution:
2    def findSubarrays(self, nums: List[int]) -> bool:
3        # Set to store sums of consecutive pairs we've seen
4        seen_sums = set()
5      
6        # Iterate through all consecutive pairs in the array
7        for i in range(len(nums) - 1):
8            # Calculate sum of current consecutive pair
9            current_sum = nums[i] + nums[i + 1]
10          
11            # Check if this sum has been seen before
12            if current_sum in seen_sums:
13                # Found two subarrays with equal sum
14                return True
15          
16            # Add current sum to the set of seen sums
17            seen_sums.add(current_sum)
18      
19        # No duplicate sums found
20        return False
21
1class Solution {
2    /**
3     * Determines if there exist two subarrays of length 2 with the same sum.
4     * 
5     * @param nums the input array of integers
6     * @return true if two subarrays of length 2 have equal sum, false otherwise
7     */
8    public boolean findSubarrays(int[] nums) {
9        // Set to store unique sums of consecutive pairs
10        Set<Integer> visitedSums = new HashSet<>();
11      
12        // Iterate through the array starting from index 1
13        for (int i = 1; i < nums.length; i++) {
14            // Calculate sum of current pair (nums[i-1] + nums[i])
15            int currentPairSum = nums[i - 1] + nums[i];
16          
17            // Try to add the sum to the set
18            // add() returns false if the element already exists
19            if (!visitedSums.add(currentPairSum)) {
20                // Sum already exists, found duplicate subarray sum
21                return true;
22            }
23        }
24      
25        // No duplicate subarray sums found
26        return false;
27    }
28}
29
1class Solution {
2public:
3    bool findSubarrays(vector<int>& nums) {
4        // Set to store sums of consecutive pairs we've seen
5        unordered_set<int> seenSums;
6      
7        // Iterate through the array starting from index 1
8        // to check all consecutive pairs
9        for (int i = 1; i < nums.size(); ++i) {
10            // Calculate sum of current pair (previous element + current element)
11            int currentSum = nums[i - 1] + nums[i];
12          
13            // Check if this sum has been seen before
14            if (seenSums.count(currentSum)) {
15                // Found two subarrays with equal sum
16                return true;
17            }
18          
19            // Add current sum to the set of seen sums
20            seenSums.insert(currentSum);
21        }
22      
23        // No duplicate sums found
24        return false;
25    }
26};
27
1/**
2 * Finds if there exist two subarrays of length 2 with equal sum
3 * @param nums - The input array of numbers
4 * @returns true if two subarrays of length 2 have equal sum, false otherwise
5 */
6function findSubarrays(nums: number[]): boolean {
7    // Set to store unique sums of consecutive pairs
8    const seenSums: Set<number> = new Set<number>();
9  
10    // Iterate through the array starting from index 1
11    for (let i = 1; i < nums.length; i++) {
12        // Calculate the sum of current element and its predecessor
13        const currentSum: number = nums[i - 1] + nums[i];
14      
15        // Check if this sum has been seen before
16        if (seenSums.has(currentSum)) {
17            // Found two subarrays with equal sum
18            return true;
19        }
20      
21        // Add the current sum to the set
22        seenSums.add(currentSum);
23    }
24  
25    // No duplicate sums found
26    return false;
27}
28

Time and Space Complexity

Time Complexity: O(n)

The algorithm iterates through the array once using pairwise(nums), which generates n-1 pairs of consecutive elements where n is the length of the array. For each pair, it performs:

  • Computing the sum a + b: O(1)
  • Checking membership in the set x in vis: O(1) average case
  • Adding to the set vis.add(x): O(1) average case

Since we perform constant-time operations for each of the n-1 pairs, the overall time complexity is O(n).

Space Complexity: O(n)

The space is used by:

  • The set vis which stores the sums of consecutive pairs. In the worst case, all n-1 sums are unique and stored in the set, requiring O(n) space.
  • The pairwise iterator uses O(1) additional space as it generates pairs on-the-fly.

Therefore, the total space complexity is O(n).

Learn more about how to find time and space complexity quickly.

Common Pitfalls

1. Confusing Overlapping vs Non-overlapping Subarrays

A common misunderstanding is thinking that the two subarrays cannot share elements. In this problem, subarrays CAN overlap - they just need to start at different indices.

Incorrect assumption: "If nums = [1, 2, 3], subarrays [1, 2] and [2, 3] cannot both be considered because they share element 2"

Correct understanding: These subarrays are valid to compare because they start at different indices (0 and 1 respectively). The problem only requires different starting positions, not completely disjoint subarrays.

2. Off-by-One Error in Loop Range

Pitfall Code:

# WRONG - iterates one element too far
for i in range(len(nums)):
    current_sum = nums[i] + nums[i + 1]  # IndexError when i = len(nums) - 1

Solution: Always use range(len(nums) - 1) when accessing nums[i] and nums[i + 1] to avoid index out of bounds errors.

3. Using a List Instead of a Set

Pitfall Code:

seen_sums = []  # Using list instead of set
for i in range(len(nums) - 1):
    current_sum = nums[i] + nums[i + 1]
    if current_sum in seen_sums:  # O(n) lookup time
        return True
    seen_sums.append(current_sum)

Issue: Using a list for membership checking makes the algorithm O(n²) instead of O(n), causing time limit exceeded on large inputs.

Solution: Always use a set for O(1) average-case lookup operations.

4. Misunderstanding "Different Indices" Requirement

Some might incorrectly check if the indices are completely non-overlapping:

Pitfall Code:

# WRONG - unnecessarily restrictive
sums_with_indices = {}
for i in range(len(nums) - 1):
    current_sum = nums[i] + nums[i + 1]
    if current_sum in sums_with_indices:
        prev_start, prev_end = sums_with_indices[current_sum]
        # Incorrectly checking for no overlap at all
        if i > prev_end or i + 1 < prev_start:  
            return True
    sums_with_indices[current_sum] = (i, i + 1)
return False

Solution: The problem only requires different starting indices. Simply checking if a sum has been seen before is sufficient - no need to track or validate index positions.

Discover Your Strengths and Weaknesses: Take Our 5-Minute Quiz to Tailor Your Study Plan:

Which of the following is a good use case for backtracking?


Recommended Readings

Want a Structured Path to Master System Design Too? Don’t Miss This!

Load More