From 551f1c7b0f27bf5f64efb829923e17abd050dc53 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Sat, 8 Feb 2025 17:22:35 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.1885 No.1885.Count Pairs in Two Arrays --- .../1885.Count Pairs in Two Arrays/README.md | 166 +++++++++++++----- .../README_EN.md | 166 +++++++++++++----- .../Solution.cpp | 20 ++- .../Solution.go | 31 ++-- .../Solution.java | 24 ++- .../Solution.js | 23 +++ .../Solution.py | 14 +- .../Solution.rs | 17 ++ .../Solution.ts | 18 ++ 9 files changed, 352 insertions(+), 127 deletions(-) create mode 100644 solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.js create mode 100644 solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.rs create mode 100644 solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.ts diff --git a/solution/1800-1899/1885.Count Pairs in Two Arrays/README.md b/solution/1800-1899/1885.Count Pairs in Two Arrays/README.md index 8e0478a1149c5..a91b9c4d9f7dd 100644 --- a/solution/1800-1899/1885.Count Pairs in Two Arrays/README.md +++ b/solution/1800-1899/1885.Count Pairs in Two Arrays/README.md @@ -61,11 +61,15 @@ tags: -### 方法一:排序 + 二分查找 +### 方法一:排序 + 双指针 -`nums1[i] + nums1[j] > nums2[i] + nums2[j]` 可以转换为 `nums1[i] - nums2[i] > -(nums1[j] - nums2[j])`。 +我们可以将题目的不等式转化为 $\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]$。 -因此,对 nums1 和 nums2 求对应元素的差值,得到 d 数组,题目就是求 `d[i] > -d[j]` 的所有数对个数。 +即对于数组 $\textit{nums}$,我们要找到所有满足 $\textit{nums}[i] + \textit{nums}[j] > 0$ 的数对 $(i, j)$。 + +我们不妨对数组 $\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$。 + +时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 为数组的长度。 @@ -74,10 +78,16 @@ tags: ```python class Solution: def countPairs(self, nums1: List[int], nums2: List[int]) -> int: - n = len(nums1) - d = [nums1[i] - nums2[i] for i in range(n)] - d.sort() - return sum(n - bisect_right(d, -v, lo=i + 1) for i, v in enumerate(d)) + nums = [a - b for a, b in zip(nums1, nums2)] + nums.sort() + l, r = 0, len(nums) - 1 + ans = 0 + while l < r: + while l < r and nums[l] + nums[r] <= 0: + l += 1 + ans += r - l + r -= 1 + return ans ``` #### Java @@ -86,23 +96,19 @@ class Solution: class Solution { public long countPairs(int[] nums1, int[] nums2) { int n = nums1.length; - int[] d = new int[n]; + int[] nums = new int[n]; for (int i = 0; i < n; ++i) { - d[i] = nums1[i] - nums2[i]; + nums[i] = nums1[i] - nums2[i]; } - Arrays.sort(d); + Arrays.sort(nums); + int l = 0, r = n - 1; long ans = 0; - for (int i = 0; i < n; ++i) { - int left = i + 1, right = n; - while (left < right) { - int mid = (left + right) >> 1; - if (d[mid] > -d[i]) { - right = mid; - } else { - left = mid + 1; - } + while (l < r) { + while (l < r && nums[l] + nums[r] <= 0) { + ++l; } - ans += n - left; + ans += r - l; + --r; } return ans; } @@ -116,13 +122,19 @@ class Solution { public: long long countPairs(vector& nums1, vector& nums2) { int n = nums1.size(); - vector d(n); - for (int i = 0; i < n; ++i) d[i] = nums1[i] - nums2[i]; - sort(d.begin(), d.end()); - long long ans = 0; + vector nums(n); for (int i = 0; i < n; ++i) { - int j = upper_bound(d.begin() + i + 1, d.end(), -d[i]) - d.begin(); - ans += n - j; + nums[i] = nums1[i] - nums2[i]; + } + ranges::sort(nums); + int l = 0, r = n - 1; + long long ans = 0; + while (l < r) { + while (l < r && nums[l] + nums[r] <= 0) { + ++l; + } + ans += r - l; + --r; } return ans; } @@ -132,30 +144,98 @@ public: #### Go ```go -func countPairs(nums1 []int, nums2 []int) int64 { +func countPairs(nums1 []int, nums2 []int) (ans int64) { n := len(nums1) - d := make([]int, n) - for i, v := range nums1 { - d[i] = v - nums2[i] + nums := make([]int, n) + for i, x := range nums1 { + nums[i] = x - nums2[i] } - sort.Ints(d) - var ans int64 - for i, v := range d { - left, right := i+1, n - for left < right { - mid := (left + right) >> 1 - if d[mid] > -v { - right = mid - } else { - left = mid + 1 - } + sort.Ints(nums) + l, r := 0, n-1 + for l < r { + for l < r && nums[l]+nums[r] <= 0 { + l++ } - ans += int64(n - left) + ans += int64(r - l) + r-- } - return ans + return +} +``` + +#### TypeScript + +```ts +function countPairs(nums1: number[], nums2: number[]): number { + const n = nums1.length; + const nums: number[] = []; + for (let i = 0; i < n; ++i) { + nums.push(nums1[i] - nums2[i]); + } + nums.sort((a, b) => a - b); + let ans = 0; + let [l, r] = [0, n - 1]; + while (l < r) { + while (l < r && nums[l] + nums[r] <= 0) { + ++l; + } + ans += r - l; + --r; + } + return ans; +} +``` + +#### Rust + +```rust +impl Solution { + pub fn count_pairs(nums1: Vec, nums2: Vec) -> i64 { + let mut nums: Vec = nums1.iter().zip(nums2.iter()).map(|(a, b)| a - b).collect(); + nums.sort(); + let mut l = 0; + let mut r = nums.len() - 1; + let mut ans = 0; + while l < r { + while l < r && nums[l] + nums[r] <= 0 { + l += 1; + } + ans += (r - l) as i64; + r -= 1; + } + ans + } } ``` +#### JavaScript + +```js +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @return {number} + */ +var countPairs = function (nums1, nums2) { + const n = nums1.length; + const nums = []; + for (let i = 0; i < n; ++i) { + nums.push(nums1[i] - nums2[i]); + } + nums.sort((a, b) => a - b); + let ans = 0; + let [l, r] = [0, n - 1]; + while (l < r) { + while (l < r && nums[l] + nums[r] <= 0) { + ++l; + } + ans += r - l; + --r; + } + return ans; +}; +``` + diff --git a/solution/1800-1899/1885.Count Pairs in Two Arrays/README_EN.md b/solution/1800-1899/1885.Count Pairs in Two Arrays/README_EN.md index d45d0abf61dd9..350f659a82d7a 100644 --- a/solution/1800-1899/1885.Count Pairs in Two Arrays/README_EN.md +++ b/solution/1800-1899/1885.Count Pairs in Two Arrays/README_EN.md @@ -60,7 +60,15 @@ tags: -### Solution 1 +### Solution 1: Sorting + Two Pointers + +We can transform the inequality in the problem to $\textit{nums1}[i] - \textit{nums2}[i] + \textit{nums1}[j] - \textit{nums2}[j] > 0$, which simplifies to $\textit{nums}[i] + \textit{nums}[j] > 0$, where $\textit{nums}[i] = \textit{nums1}[i] - \textit{nums2}[i]$. + +For the array $\textit{nums}$, we need to find all pairs $(i, j)$ that satisfy $\textit{nums}[i] + \textit{nums}[j] > 0$. + +We can sort the array $\textit{nums}$ and then use the two-pointer method. Initialize the left pointer $l = 0$ and the right pointer $r = n - 1$. Each time, we check if $\textit{nums}[l] + \textit{nums}[r]$ is less than or equal to $0$. If it is, we move the left pointer to the right in a loop until $\textit{nums}[l] + \textit{nums}[r] > 0$. At this point, all pairs with the left pointer at $l$, $l + 1$, $l + 2$, $\cdots$, $r - 1$ and the right pointer at $r$ satisfy the condition, and there are $r - l$ such pairs. We add these pairs to the answer. Then, move the right pointer to the left and continue the above process until $l \ge r$. + +The time complexity is $O(n \times \log n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the array. @@ -69,10 +77,16 @@ tags: ```python class Solution: def countPairs(self, nums1: List[int], nums2: List[int]) -> int: - n = len(nums1) - d = [nums1[i] - nums2[i] for i in range(n)] - d.sort() - return sum(n - bisect_right(d, -v, lo=i + 1) for i, v in enumerate(d)) + nums = [a - b for a, b in zip(nums1, nums2)] + nums.sort() + l, r = 0, len(nums) - 1 + ans = 0 + while l < r: + while l < r and nums[l] + nums[r] <= 0: + l += 1 + ans += r - l + r -= 1 + return ans ``` #### Java @@ -81,23 +95,19 @@ class Solution: class Solution { public long countPairs(int[] nums1, int[] nums2) { int n = nums1.length; - int[] d = new int[n]; + int[] nums = new int[n]; for (int i = 0; i < n; ++i) { - d[i] = nums1[i] - nums2[i]; + nums[i] = nums1[i] - nums2[i]; } - Arrays.sort(d); + Arrays.sort(nums); + int l = 0, r = n - 1; long ans = 0; - for (int i = 0; i < n; ++i) { - int left = i + 1, right = n; - while (left < right) { - int mid = (left + right) >> 1; - if (d[mid] > -d[i]) { - right = mid; - } else { - left = mid + 1; - } + while (l < r) { + while (l < r && nums[l] + nums[r] <= 0) { + ++l; } - ans += n - left; + ans += r - l; + --r; } return ans; } @@ -111,13 +121,19 @@ class Solution { public: long long countPairs(vector& nums1, vector& nums2) { int n = nums1.size(); - vector d(n); - for (int i = 0; i < n; ++i) d[i] = nums1[i] - nums2[i]; - sort(d.begin(), d.end()); - long long ans = 0; + vector nums(n); for (int i = 0; i < n; ++i) { - int j = upper_bound(d.begin() + i + 1, d.end(), -d[i]) - d.begin(); - ans += n - j; + nums[i] = nums1[i] - nums2[i]; + } + ranges::sort(nums); + int l = 0, r = n - 1; + long long ans = 0; + while (l < r) { + while (l < r && nums[l] + nums[r] <= 0) { + ++l; + } + ans += r - l; + --r; } return ans; } @@ -127,30 +143,98 @@ public: #### Go ```go -func countPairs(nums1 []int, nums2 []int) int64 { +func countPairs(nums1 []int, nums2 []int) (ans int64) { n := len(nums1) - d := make([]int, n) - for i, v := range nums1 { - d[i] = v - nums2[i] + nums := make([]int, n) + for i, x := range nums1 { + nums[i] = x - nums2[i] } - sort.Ints(d) - var ans int64 - for i, v := range d { - left, right := i+1, n - for left < right { - mid := (left + right) >> 1 - if d[mid] > -v { - right = mid - } else { - left = mid + 1 - } + sort.Ints(nums) + l, r := 0, n-1 + for l < r { + for l < r && nums[l]+nums[r] <= 0 { + l++ } - ans += int64(n - left) + ans += int64(r - l) + r-- } - return ans + return +} +``` + +#### TypeScript + +```ts +function countPairs(nums1: number[], nums2: number[]): number { + const n = nums1.length; + const nums: number[] = []; + for (let i = 0; i < n; ++i) { + nums.push(nums1[i] - nums2[i]); + } + nums.sort((a, b) => a - b); + let ans = 0; + let [l, r] = [0, n - 1]; + while (l < r) { + while (l < r && nums[l] + nums[r] <= 0) { + ++l; + } + ans += r - l; + --r; + } + return ans; +} +``` + +#### Rust + +```rust +impl Solution { + pub fn count_pairs(nums1: Vec, nums2: Vec) -> i64 { + let mut nums: Vec = nums1.iter().zip(nums2.iter()).map(|(a, b)| a - b).collect(); + nums.sort(); + let mut l = 0; + let mut r = nums.len() - 1; + let mut ans = 0; + while l < r { + while l < r && nums[l] + nums[r] <= 0 { + l += 1; + } + ans += (r - l) as i64; + r -= 1; + } + ans + } } ``` +#### JavaScript + +```js +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @return {number} + */ +var countPairs = function (nums1, nums2) { + const n = nums1.length; + const nums = []; + for (let i = 0; i < n; ++i) { + nums.push(nums1[i] - nums2[i]); + } + nums.sort((a, b) => a - b); + let ans = 0; + let [l, r] = [0, n - 1]; + while (l < r) { + while (l < r && nums[l] + nums[r] <= 0) { + ++l; + } + ans += r - l; + --r; + } + return ans; +}; +``` + diff --git a/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.cpp b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.cpp index 7e0651959409f..fa3ca421efed3 100644 --- a/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.cpp +++ b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.cpp @@ -2,14 +2,20 @@ class Solution { public: long long countPairs(vector& nums1, vector& nums2) { int n = nums1.size(); - vector d(n); - for (int i = 0; i < n; ++i) d[i] = nums1[i] - nums2[i]; - sort(d.begin(), d.end()); - long long ans = 0; + vector nums(n); for (int i = 0; i < n; ++i) { - int j = upper_bound(d.begin() + i + 1, d.end(), -d[i]) - d.begin(); - ans += n - j; + nums[i] = nums1[i] - nums2[i]; + } + ranges::sort(nums); + int l = 0, r = n - 1; + long long ans = 0; + while (l < r) { + while (l < r && nums[l] + nums[r] <= 0) { + ++l; + } + ans += r - l; + --r; } return ans; } -}; \ No newline at end of file +}; diff --git a/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.go b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.go index ace57e2e0aa87..e0ccfe1506a3c 100644 --- a/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.go +++ b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.go @@ -1,22 +1,17 @@ -func countPairs(nums1 []int, nums2 []int) int64 { +func countPairs(nums1 []int, nums2 []int) (ans int64) { n := len(nums1) - d := make([]int, n) - for i, v := range nums1 { - d[i] = v - nums2[i] + nums := make([]int, n) + for i, x := range nums1 { + nums[i] = x - nums2[i] } - sort.Ints(d) - var ans int64 - for i, v := range d { - left, right := i+1, n - for left < right { - mid := (left + right) >> 1 - if d[mid] > -v { - right = mid - } else { - left = mid + 1 - } + sort.Ints(nums) + l, r := 0, n-1 + for l < r { + for l < r && nums[l]+nums[r] <= 0 { + l++ } - ans += int64(n - left) + ans += int64(r - l) + r-- } - return ans -} \ No newline at end of file + return +} diff --git a/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.java b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.java index 3afce53961eed..2529d4773fe80 100644 --- a/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.java +++ b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.java @@ -1,24 +1,20 @@ class Solution { public long countPairs(int[] nums1, int[] nums2) { int n = nums1.length; - int[] d = new int[n]; + int[] nums = new int[n]; for (int i = 0; i < n; ++i) { - d[i] = nums1[i] - nums2[i]; + nums[i] = nums1[i] - nums2[i]; } - Arrays.sort(d); + Arrays.sort(nums); + int l = 0, r = n - 1; long ans = 0; - for (int i = 0; i < n; ++i) { - int left = i + 1, right = n; - while (left < right) { - int mid = (left + right) >> 1; - if (d[mid] > -d[i]) { - right = mid; - } else { - left = mid + 1; - } + while (l < r) { + while (l < r && nums[l] + nums[r] <= 0) { + ++l; } - ans += n - left; + ans += r - l; + --r; } return ans; } -} \ No newline at end of file +} diff --git a/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.js b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.js new file mode 100644 index 0000000000000..572327a0ddc20 --- /dev/null +++ b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.js @@ -0,0 +1,23 @@ +/** + * @param {number[]} nums1 + * @param {number[]} nums2 + * @return {number} + */ +var countPairs = function (nums1, nums2) { + const n = nums1.length; + const nums = []; + for (let i = 0; i < n; ++i) { + nums.push(nums1[i] - nums2[i]); + } + nums.sort((a, b) => a - b); + let ans = 0; + let [l, r] = [0, n - 1]; + while (l < r) { + while (l < r && nums[l] + nums[r] <= 0) { + ++l; + } + ans += r - l; + --r; + } + return ans; +}; diff --git a/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.py b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.py index 9aa3001a47885..0205f9bad27a6 100644 --- a/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.py +++ b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.py @@ -1,6 +1,12 @@ class Solution: def countPairs(self, nums1: List[int], nums2: List[int]) -> int: - n = len(nums1) - d = [nums1[i] - nums2[i] for i in range(n)] - d.sort() - return sum(n - bisect_right(d, -v, lo=i + 1) for i, v in enumerate(d)) + nums = [a - b for a, b in zip(nums1, nums2)] + nums.sort() + l, r = 0, len(nums) - 1 + ans = 0 + while l < r: + while l < r and nums[l] + nums[r] <= 0: + l += 1 + ans += r - l + r -= 1 + return ans diff --git a/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.rs b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.rs new file mode 100644 index 0000000000000..c48a4033ed8d1 --- /dev/null +++ b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.rs @@ -0,0 +1,17 @@ +impl Solution { + pub fn count_pairs(nums1: Vec, nums2: Vec) -> i64 { + let mut nums: Vec = nums1.iter().zip(nums2.iter()).map(|(a, b)| a - b).collect(); + nums.sort(); + let mut l = 0; + let mut r = nums.len() - 1; + let mut ans = 0; + while l < r { + while l < r && nums[l] + nums[r] <= 0 { + l += 1; + } + ans += (r - l) as i64; + r -= 1; + } + ans + } +} diff --git a/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.ts b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.ts new file mode 100644 index 0000000000000..639d80f0c7875 --- /dev/null +++ b/solution/1800-1899/1885.Count Pairs in Two Arrays/Solution.ts @@ -0,0 +1,18 @@ +function countPairs(nums1: number[], nums2: number[]): number { + const n = nums1.length; + const nums: number[] = []; + for (let i = 0; i < n; ++i) { + nums.push(nums1[i] - nums2[i]); + } + nums.sort((a, b) => a - b); + let ans = 0; + let [l, r] = [0, n - 1]; + while (l < r) { + while (l < r && nums[l] + nums[r] <= 0) { + ++l; + } + ans += r - l; + --r; + } + return ans; +}