Formatted question description: https://leetcode.ca/all/1865.html

1865. Finding Pairs With a Certain Sum

Level

Medium

Description

You are given two integer arrays nums1 and nums2. You are tasked to implement a data structure that supports queries of two types:

  1. Add a positive integer to an element of a given index in the array nums2.
  2. Count the number of pairs (i, j) such that nums1[i] + nums2[j] equals a given value (0 <= i < nums1.length and 0 <= j < nums2.length).

Implement the FindSumPairs class:

  • FindSumPairs(int[] nums1, int[] nums2) Initializes the FindSumPairs object with two integer arrays nums1 and nums2.
  • void add(int index, int val) Adds val to nums2[index], i.e., apply nums2[index] += val.
  • int count(int tot) Returns the number of pairs (i, j) such that nums1[i] + nums2[j] == tot.

Example 1:

Input
["FindSumPairs", "count", "add", "count", "count", "add", "add", "count"]
[[[1, 1, 2, 2, 2, 3], [1, 4, 5, 2, 5, 4]], [7], [3, 2], [8], [4], [0, 1], [1, 1], [7]]
Output
[null, 8, null, 2, 1, null, null, 11]

Explanation
FindSumPairs findSumPairs = new FindSumPairs([1, 1, 2, 2, 2, 3], [1, 4, 5, 2, 5, 4]);
findSumPairs.count(7);  // return 8; pairs (2,2), (3,2), (4,2), (2,4), (3,4), (4,4) make 2 + 5 and pairs (5,1), (5,5) make 3 + 4
findSumPairs.add(3, 2); // now nums2 = [1,4,5,4,5,4]
findSumPairs.count(8);  // return 2; pairs (5,2), (5,4) make 3 + 5
findSumPairs.count(4);  // return 1; pair (5,0) makes 3 + 1
findSumPairs.add(0, 1); // now nums2 = [2,4,5,4,5,4]
findSumPairs.add(1, 1); // now nums2 = [2,5,5,4,5,4]
findSumPairs.count(7);  // return 11; pairs (2,1), (2,2), (2,4), (3,1), (3,2), (3,4), (4,1), (4,2), (4,4) make 2 + 5 and pairs (5,3), (5,5) make 3 + 4

Constraints:

  • 1 <= nums1.length <= 1000
  • 1 <= nums2.length <= 10^5
  • 1 <= nums1[i] <= 10^9
  • 1 <= nums2[i] <= 10^5
  • 0 <= index < nums2.length
  • 1 <= val <= 10^5
  • 1 <= tot <= 10^9
  • At most 1000 calls are made to add and count each.

Solution

In the class FindSumPairs, maintain the array nums2 and two maps map1 and map2 that store each number’s occurrences in nums1 and nums2 respectively.

For the constructor, initialize nums2 with the given nums2, and initialize the two maps with the given two arrays.

For add, obtain the original value and the new value of nums2[index], update map2 with the original value and the new value, and update nums2[index] with the new value.

For count, loop over map1, and for each entry, calculate the count from map2 that has sum equal to tot, and calculate the number of pairs. Finally, return the number of pairs.

class FindSumPairs {
    int[] nums2;
    Map<Integer, Integer> map1;
    Map<Integer, Integer> map2;

    public FindSumPairs(int[] nums1, int[] nums2) {
        this.nums2 = nums2;
        map1 = new HashMap<Integer, Integer>();
        map2 = new HashMap<Integer, Integer>();
        for (int num : nums1)
            map1.put(num, map1.getOrDefault(num, 0) + 1);
        for (int num : nums2)
            map2.put(num, map2.getOrDefault(num, 0) + 1);
    }
    
    public void add(int index, int val) {
        int prev = nums2[index], curr = nums2[index] + val;
        int count1 = map2.get(prev) - 1, count2 = map2.getOrDefault(curr, 0) + 1;
        if (count1 > 0)
            map2.put(prev, count1);
        else
            map2.remove(prev);
        map2.put(curr, count2);
        nums2[index] = curr;
    }
    
    public int count(int tot) {
        int totalCount = 0;
        for (Map.Entry<Integer, Integer> entry : map1.entrySet()) {
            int num = entry.getKey(), count1 = entry.getValue();
            int count2 = map2.getOrDefault(tot - num, 0);
            totalCount += count1 * count2;
        }
        return totalCount;
    }
}

/**
 * Your FindSumPairs object will be instantiated and called as such:
 * FindSumPairs obj = new FindSumPairs(nums1, nums2);
 * obj.add(index,val);
 * int param_2 = obj.count(tot);
 */

All Problems

All Solutions