Welcome to Subscribe On Youtube
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:
- Add a positive integer to an element of a given index in the array
nums2. - Count the number of pairs
(i, j)such thatnums1[i] + nums2[j]equals a given value (0 <= i < nums1.lengthand0 <= j < nums2.length).
Implement the FindSumPairs class:
FindSumPairs(int[] nums1, int[] nums2)Initializes theFindSumPairsobject with two integer arraysnums1andnums2.void add(int index, int val)Addsvaltonums2[index], i.e., applynums2[index] += val.int count(int tot)Returns the number of pairs(i, j)such thatnums1[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 <= 10001 <= nums2.length <= 10^51 <= nums1[i] <= 10^91 <= nums2[i] <= 10^50 <= index < nums2.length1 <= val <= 10^51 <= tot <= 10^9- At most
1000calls are made toaddandcounteach.
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); */ ############ class FindSumPairs { private int[] nums1; private int[] nums2; private Map<Integer, Integer> cnt = new HashMap<>(); public FindSumPairs(int[] nums1, int[] nums2) { this.nums1 = nums1; this.nums2 = nums2; for (int v : nums2) { cnt.put(v, cnt.getOrDefault(v, 0) + 1); } } public void add(int index, int val) { int old = nums2[index]; cnt.put(old, cnt.get(old) - 1); cnt.put(old + val, cnt.getOrDefault(old + val, 0) + 1); nums2[index] += val; } public int count(int tot) { int ans = 0; for (int v : nums1) { ans += cnt.getOrDefault(tot - v, 0); } return ans; } } /** * 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); */ -
// OJ: https://leetcode.com/problems/finding-pairs-with-a-certain-sum/ // Time: // FindSumPairs: O(B) // add: O(1) // count: O(A) // Space: O(A + B) class FindSumPairs { vector<int> A, B; unordered_map<int, int> m; public: FindSumPairs(vector<int>& A, vector<int>& B): A(A), B(B) { for (int n : B) m[n]++; } void add(int index, int val) { int n = B[index]; if (--m[n] == 0) m.erase(n); B[index] += val; m[B[index]]++; } int count(int tot) { int ans = 0; for (int a : A) { if (m.count(tot - a)) ans += m[tot - a]; } return ans; } }; -
class FindSumPairs: def __init__(self, nums1: List[int], nums2: List[int]): self.nums1 = nums1 self.nums2 = nums2 self.cnt = Counter(nums2) def add(self, index: int, val: int) -> None: old = self.nums2[index] self.cnt[old] -= 1 self.cnt[old + val] += 1 self.nums2[index] += val def count(self, tot: int) -> int: return sum(self.cnt[tot - v] for v in self.nums1) # Your FindSumPairs object will be instantiated and called as such: # obj = FindSumPairs(nums1, nums2) # obj.add(index,val) # param_2 = obj.count(tot) ############ # 1865. Finding Pairs With a Certain Sum # https://leetcode.com/problems/finding-pairs-with-a-certain-sum/ class FindSumPairs: def __init__(self, nums1: List[int], nums2: List[int]): self.nums2 = nums2 self.mp1 = collections.Counter(nums1) self.mp2 = collections.Counter(nums2) def add(self, index: int, val: int) -> None: num = self.nums2[index] self.mp2[num] -= 1 self.nums2[index] += val self.mp2[num + val] += 1 def count(self, tot: int) -> int: count = 0 mp = collections.defaultdict(int) for k,v in self.mp1.items(): if tot - k in self.mp2: count += v * self.mp2[tot - k] return count # Your FindSumPairs object will be instantiated and called as such: # obj = FindSumPairs(nums1, nums2) # obj.add(index,val) # param_2 = obj.count(tot) -
type FindSumPairs struct { nums1 []int nums2 []int cnt map[int]int } func Constructor(nums1 []int, nums2 []int) FindSumPairs { cnt := map[int]int{} for _, v := range nums2 { cnt[v]++ } return FindSumPairs{nums1, nums2, cnt} } func (this *FindSumPairs) Add(index int, val int) { old := this.nums2[index] this.cnt[old]-- this.cnt[old+val]++ this.nums2[index] += val } func (this *FindSumPairs) Count(tot int) (ans int) { for _, v := range this.nums1 { ans += this.cnt[tot-v] } return } /** * Your FindSumPairs object will be instantiated and called as such: * obj := Constructor(nums1, nums2); * obj.Add(index,val); * param_2 := obj.Count(tot); */