@@ -61,11 +61,15 @@ tags:
61
61
62
62
<!-- solution:start -->
63
63
64
- ### 方法一:排序 + 二分查找
64
+ ### 方法一:排序 + 双指针
65
65
66
- ` nums1[i] + nums1[j] > nums2[i] + nums2[j] ` 可以转换为 ` nums1[i] - nums2 [i] > -( nums1[j ] - nums2[j]) ` 。
66
+ 我们可以将题目的不等式转化为 $\textit{ nums1} [ i] - \textit{nums2} [ i ] + \textit{ nums1} [ j] - \textit{ nums2} [ j ] > 0$,即 $\textit{nums} [ i ] + \textit{nums} [ j ] > 0$,其中 $\textit{nums} [ i] = \textit{ nums1} [ i ] - \textit{ nums2} [ i ] $ 。
67
67
68
- 因此,对 nums1 和 nums2 求对应元素的差值,得到 d 数组,题目就是求 ` d[i] > -d[j] ` 的所有数对个数。
68
+ 即对于数组 $\textit{nums}$,我们要找到所有满足 $\textit{nums}[ i] + \textit{nums}[ j] > 0$ 的数对 $(i, j)$。
69
+
70
+ 我们不妨对数组 $\textit{nums}$ 进行排序,然后使用双指针的方法,初始化左指针 $l = 0$,右指针 $r = n - 1$。每一次,我们判断 $\textit{nums}[ l] + \textit{nums}[ r] $ 是否小于等于 $0$,如果是,我们循环将左指针右移,直到 $\textit{nums}[ l] + \textit{nums}[ r] > 0$,此时,以 $l$, $l + 1$, $l + 2$, $\cdots$, $r - 1$ 为左指针,且 $r$ 为右指针的所有数对都满足条件,共有 $r - l$ 个数对,我们将其加入答案中。然后将右指针左移,继续进行上述操作,直到 $l \ge r$。
71
+
72
+ 时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。
69
73
70
74
<!-- tabs:start -->
71
75
@@ -74,10 +78,16 @@ tags:
74
78
``` python
75
79
class Solution :
76
80
def countPairs (self , nums1 : List[int ], nums2 : List[int ]) -> int :
77
- n = len (nums1)
78
- d = [nums1[i] - nums2[i] for i in range (n)]
79
- d.sort()
80
- return sum (n - bisect_right(d, - v, lo = i + 1 ) for i, v in enumerate (d))
81
+ nums = [a - b for a, b in zip (nums1, nums2)]
82
+ nums.sort()
83
+ l, r = 0 , len (nums) - 1
84
+ ans = 0
85
+ while l < r:
86
+ while l < r and nums[l] + nums[r] <= 0 :
87
+ l += 1
88
+ ans += r - l
89
+ r -= 1
90
+ return ans
81
91
```
82
92
83
93
#### Java
@@ -86,23 +96,19 @@ class Solution:
86
96
class Solution {
87
97
public long countPairs (int [] nums1 , int [] nums2 ) {
88
98
int n = nums1. length;
89
- int [] d = new int [n];
99
+ int [] nums = new int [n];
90
100
for (int i = 0 ; i < n; ++ i) {
91
- d [i] = nums1[i] - nums2[i];
101
+ nums [i] = nums1[i] - nums2[i];
92
102
}
93
- Arrays . sort(d);
103
+ Arrays . sort(nums);
104
+ int l = 0 , r = n - 1 ;
94
105
long ans = 0 ;
95
- for (int i = 0 ; i < n; ++ i) {
96
- int left = i + 1 , right = n;
97
- while (left < right) {
98
- int mid = (left + right) >> 1 ;
99
- if (d[mid] > - d[i]) {
100
- right = mid;
101
- } else {
102
- left = mid + 1 ;
103
- }
106
+ while (l < r) {
107
+ while (l < r && nums[l] + nums[r] <= 0 ) {
108
+ ++ l;
104
109
}
105
- ans += n - left;
110
+ ans += r - l;
111
+ -- r;
106
112
}
107
113
return ans;
108
114
}
@@ -116,13 +122,19 @@ class Solution {
116
122
public:
117
123
long long countPairs(vector<int >& nums1, vector<int >& nums2) {
118
124
int n = nums1.size();
119
- vector<int > d(n);
120
- for (int i = 0; i < n; ++i) d[ i] = nums1[ i] - nums2[ i] ;
121
- sort(d.begin(), d.end());
122
- long long ans = 0;
125
+ vector<int > nums(n);
123
126
for (int i = 0; i < n; ++i) {
124
- int j = upper_bound(d.begin() + i + 1, d.end(), -d[ i] ) - d.begin();
125
- ans += n - j;
127
+ nums[ i] = nums1[ i] - nums2[ i] ;
128
+ }
129
+ ranges::sort(nums);
130
+ int l = 0, r = n - 1;
131
+ long long ans = 0;
132
+ while (l < r) {
133
+ while (l < r && nums[ l] + nums[ r] <= 0) {
134
+ ++l;
135
+ }
136
+ ans += r - l;
137
+ --r;
126
138
}
127
139
return ans;
128
140
}
@@ -132,30 +144,98 @@ public:
132
144
#### Go
133
145
134
146
```go
135
- func countPairs(nums1 []int, nums2 []int) int64 {
147
+ func countPairs(nums1 []int, nums2 []int) (ans int64) {
136
148
n := len(nums1)
137
- d := make([]int, n)
138
- for i, v := range nums1 {
139
- d [i] = v - nums2[i]
149
+ nums := make([]int, n)
150
+ for i, x := range nums1 {
151
+ nums [i] = x - nums2[i]
140
152
}
141
- sort.Ints(d)
142
- var ans int64
143
- for i, v := range d {
144
- left, right := i+1, n
145
- for left < right {
146
- mid := (left + right) >> 1
147
- if d[mid] > -v {
148
- right = mid
149
- } else {
150
- left = mid + 1
151
- }
153
+ sort.Ints(nums)
154
+ l, r := 0, n-1
155
+ for l < r {
156
+ for l < r && nums[l]+nums[r] <= 0 {
157
+ l++
152
158
}
153
- ans += int64(n - left)
159
+ ans += int64(r - l)
160
+ r--
154
161
}
155
- return ans
162
+ return
163
+ }
164
+ ```
165
+
166
+ #### TypeScript
167
+
168
+ ``` ts
169
+ function countPairs(nums1 : number [], nums2 : number []): number {
170
+ const n = nums1 .length ;
171
+ const nums: number [] = [];
172
+ for (let i = 0 ; i < n ; ++ i ) {
173
+ nums .push (nums1 [i ] - nums2 [i ]);
174
+ }
175
+ nums .sort ((a , b ) => a - b );
176
+ let ans = 0 ;
177
+ let [l, r] = [0 , n - 1 ];
178
+ while (l < r ) {
179
+ while (l < r && nums [l ] + nums [r ] <= 0 ) {
180
+ ++ l ;
181
+ }
182
+ ans += r - l ;
183
+ -- r ;
184
+ }
185
+ return ans ;
186
+ }
187
+ ```
188
+
189
+ #### Rust
190
+
191
+ ``` rust
192
+ impl Solution {
193
+ pub fn count_pairs (nums1 : Vec <i32 >, nums2 : Vec <i32 >) -> i64 {
194
+ let mut nums : Vec <i32 > = nums1 . iter (). zip (nums2 . iter ()). map (| (a , b )| a - b ). collect ();
195
+ nums . sort ();
196
+ let mut l = 0 ;
197
+ let mut r = nums . len () - 1 ;
198
+ let mut ans = 0 ;
199
+ while l < r {
200
+ while l < r && nums [l ] + nums [r ] <= 0 {
201
+ l += 1 ;
202
+ }
203
+ ans += (r - l ) as i64 ;
204
+ r -= 1 ;
205
+ }
206
+ ans
207
+ }
156
208
}
157
209
```
158
210
211
+ #### JavaScript
212
+
213
+ ``` js
214
+ /**
215
+ * @param {number[]} nums1
216
+ * @param {number[]} nums2
217
+ * @return {number}
218
+ */
219
+ var countPairs = function (nums1 , nums2 ) {
220
+ const n = nums1 .length ;
221
+ const nums = [];
222
+ for (let i = 0 ; i < n; ++ i) {
223
+ nums .push (nums1[i] - nums2[i]);
224
+ }
225
+ nums .sort ((a , b ) => a - b);
226
+ let ans = 0 ;
227
+ let [l, r] = [0 , n - 1 ];
228
+ while (l < r) {
229
+ while (l < r && nums[l] + nums[r] <= 0 ) {
230
+ ++ l;
231
+ }
232
+ ans += r - l;
233
+ -- r;
234
+ }
235
+ return ans;
236
+ };
237
+ ```
238
+
159
239
<!-- tabs: end -->
160
240
161
241
<!-- solution: end -->
0 commit comments