@@ -61,11 +61,15 @@ tags:
6161
6262<!-- solution:start -->
6363
64- ### 方法一:排序 + 二分查找
64+ ### 方法一:排序 + 双指针
6565
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 ] $ 。
6767
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$ 为数组的长度。
6973
7074<!-- tabs:start -->
7175
@@ -74,10 +78,16 @@ tags:
7478``` python
7579class Solution :
7680 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
8191```
8292
8393#### Java
@@ -86,23 +96,19 @@ class Solution:
8696class Solution {
8797 public long countPairs (int [] nums1 , int [] nums2 ) {
8898 int n = nums1. length;
89- int [] d = new int [n];
99+ int [] nums = new int [n];
90100 for (int i = 0 ; i < n; ++ i) {
91- d [i] = nums1[i] - nums2[i];
101+ nums [i] = nums1[i] - nums2[i];
92102 }
93- Arrays . sort(d);
103+ Arrays . sort(nums);
104+ int l = 0 , r = n - 1 ;
94105 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;
104109 }
105- ans += n - left;
110+ ans += r - l;
111+ -- r;
106112 }
107113 return ans;
108114 }
@@ -116,13 +122,19 @@ class Solution {
116122public:
117123 long long countPairs(vector<int >& nums1, vector<int >& nums2) {
118124 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);
123126 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;
126138 }
127139 return ans;
128140 }
@@ -132,30 +144,98 @@ public:
132144#### Go
133145
134146```go
135- func countPairs(nums1 []int, nums2 []int) int64 {
147+ func countPairs(nums1 []int, nums2 []int) (ans int64) {
136148 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]
140152 }
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++
152158 }
153- ans += int64(n - left)
159+ ans += int64(r - l)
160+ r--
154161 }
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+ }
156208}
157209```
158210
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+
159239<!-- tabs: end -->
160240
161241<!-- solution: end -->
0 commit comments