@@ -80,33 +80,35 @@ findSumPairs.count(7); // 返回 11 ;下标对 (2,1), (2,2), (2,4), (3,1), (3
8080
8181### 方法一:哈希表
8282
83- 我们可以用哈希表 ` cnt ` 统计数组 ` nums2 ` 中每个数字出现的次数 。
83+ 我们注意到,数组 $\textit{nums1}$ 的长度不超过 ${10}^3$,数组 $\textit{ nums2}$ 的长度达到 ${10}^5$,因此,如果直接暴力枚举所有下标对 $(i, j)$,计算 $\textit{nums1} [ i ] + \textit{nums2} [ j ] $ 是否等于指定值 $\textit{tot}$,那么会超出时间限制 。
8484
85- 对于 ` add ` 操作,我们需要更新哈希表中 ` nums2[index] ` 的值,即 ` cnt[ nums2[index]] -= 1 ` ,然后更新 ` nums2[index] += val ` ,最后更新哈希表中 ` nums2[index] ` 的值,即 ` cnt[nums2[index]] += 1 ` 。
85+ 能否只枚举长度较短的数组 $\textit{nums1}$ 呢?答案是可以的。我们用一个哈希表 $\textit{cnt}$ 统计数组 $\textit{ nums2}$ 中每个元素出现的次数,然后枚举数组 $\textit{nums1}$ 中的每个元素 $x$,计算 $\textit{cnt} [ \textit{tot} - x ] $ 的值之和即可 。
8686
87- 对于 ` count ` 操作,我们遍历数组 ` nums1 ` ,对于每个数字 ` v ` ,我们需要统计满足 ` tot - v ` 的数字出现的次数,即 ` cnt[tot - v] ` ,然后将其累加到答案中 。
87+ 在调用 $\text{add}$ 方法时,我们需要先将 $\textit{nums2} [ index ] $ 对应的值从 $\textit{cnt}$ 中减去 $1$,然后将 $\textit{nums2} [ index ] $ 的值加上 $\textit{val}$,最后将 $\textit{nums2} [ index ] $ 对应的值加上 $1$ 。
8888
89- 时间复杂度:对于 ` add ` 操作,时间复杂度为 $O(1)$,对于 ` count ` 操作,时间复杂度为 $O(n)$,其中 $n$ 为数组 ` nums1 ` 的长度。空间复杂度 $O(m)$,其中 $m$ 为数组 ` nums2 ` 的长度。
89+ 在调用 $\text{count}$ 方法时,我们只需要遍历数组 $\textit{nums1}$,对于每个元素 $x$,计算 $\textit{cnt}[ \textit{tot} - x] $ 的值之和即可。
90+
91+ 时间复杂度 $O(n \times q)$,空间复杂度 $O(m)$。其中 $n$ 和 $m$ 分别是数组 $\textit{nums1}$ 和 $\textit{nums2}$ 的长度,而 $q$ 是调用 $\text{count}$ 方法的次数。
9092
9193<!-- tabs:start -->
9294
9395#### Python3
9496
9597``` python
9698class FindSumPairs :
99+
97100 def __init__ (self , nums1 : List[int ], nums2 : List[int ]):
101+ self .cnt = Counter(nums2)
98102 self .nums1 = nums1
99103 self .nums2 = nums2
100- self .cnt = Counter(nums2)
101104
102105 def add (self , index : int , val : int ) -> None :
103- old = self .nums2[index]
104- self .cnt[old] -= 1
105- self .cnt[old + val] += 1
106+ self .cnt[self .nums2[index]] -= 1
106107 self .nums2[index] += val
108+ self .cnt[self .nums2[index]] += 1
107109
108110 def count (self , tot : int ) -> int :
109- return sum (self .cnt[tot - v ] for v in self .nums1)
111+ return sum (self .cnt[tot - x ] for x in self .nums1)
110112
111113
112114# Your FindSumPairs object will be instantiated and called as such:
@@ -126,22 +128,21 @@ class FindSumPairs {
126128 public FindSumPairs (int [] nums1 , int [] nums2 ) {
127129 this . nums1 = nums1;
128130 this . nums2 = nums2;
129- for (int v : nums2) {
130- cnt. put(v, cnt . getOrDefault(v, 0 ) + 1 );
131+ for (int x : nums2) {
132+ cnt. merge(x, 1 , Integer :: sum );
131133 }
132134 }
133135
134136 public void add (int index , int val ) {
135- int old = nums2[index];
136- cnt. put(old, cnt. get(old) - 1 );
137- cnt. put(old + val, cnt. getOrDefault(old + val, 0 ) + 1 );
137+ cnt. merge(nums2[index], - 1 , Integer :: sum);
138138 nums2[index] += val;
139+ cnt. merge(nums2[index], 1 , Integer :: sum);
139140 }
140141
141142 public int count (int tot ) {
142143 int ans = 0 ;
143- for (int v : nums1) {
144- ans += cnt. getOrDefault(tot - v , 0 );
144+ for (int x : nums1) {
145+ ans += cnt. getOrDefault(tot - x , 0 );
145146 }
146147 return ans;
147148 }
@@ -163,22 +164,21 @@ public:
163164 FindSumPairs(vector<int >& nums1, vector<int >& nums2) {
164165 this->nums1 = nums1;
165166 this->nums2 = nums2;
166- for (int& v : nums2) {
167- ++cnt[ v ] ;
167+ for (int x : nums2) {
168+ ++cnt[ x ] ;
168169 }
169170 }
170171
171172 void add(int index, int val) {
172- int old = nums2[index];
173- --cnt[old];
174- ++cnt[old + val];
173+ --cnt[nums2[index]];
175174 nums2[index] += val;
175+ ++cnt[nums2[index]];
176176 }
177177
178178 int count (int tot) {
179179 int ans = 0;
180- for (int& v : nums1) {
181- ans += cnt[ tot - v ] ;
180+ for (int x : nums1) {
181+ ans += cnt[ tot - x ] ;
182182 }
183183 return ans;
184184 }
@@ -208,22 +208,21 @@ type FindSumPairs struct {
208208
209209func Constructor(nums1 []int, nums2 []int) FindSumPairs {
210210 cnt := map[int]int{}
211- for _, v := range nums2 {
212- cnt[v ]++
211+ for _, x := range nums2 {
212+ cnt[x ]++
213213 }
214214 return FindSumPairs{nums1, nums2, cnt}
215215}
216216
217217func (this *FindSumPairs) Add(index int, val int) {
218- old := this.nums2[index]
219- this.cnt[old]--
220- this.cnt[old+val]++
218+ this.cnt[this.nums2[index]]--
221219 this.nums2[index] += val
220+ this.cnt[this.nums2[index]]++
222221}
223222
224223func (this *FindSumPairs) Count(tot int) (ans int) {
225- for _, v := range this.nums1 {
226- ans += this.cnt[tot-v ]
224+ for _, x := range this.nums1 {
225+ ans += this.cnt[tot-x ]
227226 }
228227 return
229228}
@@ -236,6 +235,147 @@ func (this *FindSumPairs) Count(tot int) (ans int) {
236235 */
237236```
238237
238+ #### TypeScript
239+
240+ ``` ts
241+ class FindSumPairs {
242+ private nums1: number [];
243+ private nums2: number [];
244+ private cnt: Map <number , number >;
245+
246+ constructor (nums1 : number [], nums2 : number []) {
247+ this .nums1 = nums1 ;
248+ this .nums2 = nums2 ;
249+ this .cnt = new Map ();
250+ for (const x of nums2 ) {
251+ this .cnt .set (x , (this .cnt .get (x ) || 0 ) + 1 );
252+ }
253+ }
254+
255+ add(index : number , val : number ): void {
256+ const old = this .nums2 [index ];
257+ this .cnt .set (old , this .cnt .get (old )! - 1 );
258+ this .nums2 [index ] += val ;
259+ const now = this .nums2 [index ];
260+ this .cnt .set (now , (this .cnt .get (now ) || 0 ) + 1 );
261+ }
262+
263+ count(tot : number ): number {
264+ return this .nums1 .reduce ((acc , x ) => acc + (this .cnt .get (tot - x ) || 0 ), 0 );
265+ }
266+ }
267+
268+ /**
269+ * Your FindSumPairs object will be instantiated and called as such:
270+ * var obj = new FindSumPairs(nums1, nums2)
271+ * obj.add(index,val)
272+ * var param_2 = obj.count(tot)
273+ */
274+ ```
275+
276+ #### JavaScript
277+
278+ ``` js
279+ /**
280+ * @param {number[]} nums1
281+ * @param {number[]} nums2
282+ */
283+ var FindSumPairs = function (nums1 , nums2 ) {
284+ this .nums1 = nums1;
285+ this .nums2 = nums2;
286+ this .cnt = new Map ();
287+ for (const x of nums2) {
288+ this .cnt .set (x, (this .cnt .get (x) || 0 ) + 1 );
289+ }
290+ };
291+
292+ /**
293+ * @param {number} index
294+ * @param {number} val
295+ * @return {void}
296+ */
297+ FindSumPairs .prototype .add = function (index , val ) {
298+ const old = this .nums2 [index];
299+ this .cnt .set (old, this .cnt .get (old) - 1 );
300+ this .nums2 [index] += val;
301+ const now = this .nums2 [index];
302+ this .cnt .set (now, (this .cnt .get (now) || 0 ) + 1 );
303+ };
304+
305+ /**
306+ * @param {number} tot
307+ * @return {number}
308+ */
309+ FindSumPairs .prototype .count = function (tot ) {
310+ return this .nums1 .reduce ((acc , x ) => acc + (this .cnt .get (tot - x) || 0 ), 0 );
311+ };
312+
313+ /**
314+ * Your FindSumPairs object will be instantiated and called as such:
315+ * var obj = new FindSumPairs(nums1, nums2)
316+ * obj.add(index,val)
317+ * var param_2 = obj.count(tot)
318+ */
319+ ```
320+
321+ #### C#
322+
323+ ``` cs
324+ public class FindSumPairs {
325+ private int [] nums1 ;
326+ private int [] nums2 ;
327+ private Dictionary <int , int > cnt = new Dictionary <int , int >();
328+
329+ public FindSumPairs (int [] nums1 , int [] nums2 ) {
330+ this .nums1 = nums1 ;
331+ this .nums2 = nums2 ;
332+ foreach (int x in nums2 ) {
333+ if (cnt .ContainsKey (x )) {
334+ cnt [x ]++ ;
335+ } else {
336+ cnt [x ] = 1 ;
337+ }
338+ }
339+ }
340+
341+ public void Add (int index , int val ) {
342+ int oldVal = nums2 [index ];
343+ if (cnt .TryGetValue (oldVal , out int oldCount )) {
344+ if (oldCount == 1 ) {
345+ cnt .Remove (oldVal );
346+ } else {
347+ cnt [oldVal ] = oldCount - 1 ;
348+ }
349+ }
350+ nums2 [index ] += val ;
351+ int newVal = nums2 [index ];
352+ if (cnt .TryGetValue (newVal , out int newCount )) {
353+ cnt [newVal ] = newCount + 1 ;
354+ } else {
355+ cnt [newVal ] = 1 ;
356+ }
357+ }
358+
359+ public int Count (int tot ) {
360+ int ans = 0 ;
361+ foreach (int x in nums1 ) {
362+ int target = tot - x ;
363+ if (cnt .TryGetValue (target , out int count )) {
364+ ans += count ;
365+ }
366+ }
367+ return ans ;
368+ }
369+ }
370+
371+ /**
372+ * Your FindSumPairs object will be instantiated and called as such:
373+ * FindSumPairs obj = new FindSumPairs(nums1, nums2);
374+ * obj.Add(index,val);
375+ * int param_2 = obj.Count(tot);
376+ */
377+ ```
378+
239379<!-- tabs:end -->
240380
241381<!-- solution:end -->
0 commit comments