Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit b9dc687

Browse files
authored
feat: add solutions to lc problem: No.1885 (doocs#4049)
No.1885.Count Pairs in Two Arrays
1 parent 652dde4 commit b9dc687

File tree

9 files changed

+352
-127
lines changed

9 files changed

+352
-127
lines changed

solution/1800-1899/1885.Count Pairs in Two Arrays/README.md

Lines changed: 123 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -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
7579
class 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:
8696
class 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 {
116122
public:
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

Comments
 (0)