Skip to content

Commit 0caa4cb

Browse files
committed
feat: add solutions to lc problem: No.0719
No.0719.Find K-th Smallest Pair Distance
1 parent 41b4df3 commit 0caa4cb

File tree

6 files changed

+327
-3
lines changed

6 files changed

+327
-3
lines changed

solution/0700-0799/0719.Find K-th Smallest Pair Distance/README.md

Lines changed: 116 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,22 +53,71 @@
5353

5454
<!-- 这里可写通用的实现逻辑 -->
5555

56+
**方法一:排序 + 二分查找**
57+
58+
先对 $nums$ 数组进行排序,然后在 $[0, nums[n-1]-nums[0]]$ 范围内二分枚举数对距离 $dist$,若 $nums$ 中数对距离小于等于 $dist$ 的数量 $cnt$ 大于等于 $k$,则尝试缩小 $dist$,否则尝试扩大 $dist$。
59+
60+
时间复杂度 $O(nlogn×logm)$,其中 $n$ 表示 $nums$ 的长度,$m$ 表示 $nums$ 中两个数的最大差值。
61+
5662
<!-- tabs:start -->
5763

5864
### **Python3**
5965

6066
<!-- 这里可写当前语言的特殊实现逻辑 -->
6167

6268
```python
63-
69+
class Solution:
70+
def smallestDistancePair(self, nums: List[int], k: int) -> int:
71+
def count(dist):
72+
cnt = 0
73+
for i, b in enumerate(nums):
74+
a = b - dist
75+
j = bisect_left(nums, a, 0, i)
76+
cnt += i - j
77+
return cnt
78+
79+
nums.sort()
80+
return bisect_left(range(nums[-1] - nums[0]), k, key=count)
6481
```
6582

6683
### **Java**
6784

6885
<!-- 这里可写当前语言的特殊实现逻辑 -->
6986

7087
```java
88+
class Solution {
89+
public int smallestDistancePair(int[] nums, int k) {
90+
Arrays.sort(nums);
91+
int left = 0, right = nums[nums.length - 1] - nums[0];
92+
while (left < right) {
93+
int mid = (left + right) >> 1;
94+
if (count(mid, nums) >= k) {
95+
right = mid;
96+
} else {
97+
left = mid + 1;
98+
}
99+
}
100+
return left;
101+
}
71102

103+
private int count(int dist, int[] nums) {
104+
int cnt = 0;
105+
for (int i = 0; i < nums.length; ++i) {
106+
int left = 0, right = i;
107+
while (left < right) {
108+
int mid = (left + right) >> 1;
109+
int target = nums[i] - dist;
110+
if (nums[mid] >= target) {
111+
right = mid;
112+
} else {
113+
left = mid + 1;
114+
}
115+
}
116+
cnt += i - left;
117+
}
118+
return cnt;
119+
}
120+
}
72121
```
73122

74123
### **TypeScript**
@@ -100,6 +149,72 @@ function smallestDistancePair(nums: number[], k: number): number {
100149
}
101150
```
102151

152+
### **C++**
153+
154+
```cpp
155+
class Solution {
156+
public:
157+
int smallestDistancePair(vector<int>& nums, int k) {
158+
sort(nums.begin(), nums.end());
159+
int left = 0, right = nums.back() - nums.front();
160+
while (left < right)
161+
{
162+
int mid = (left + right) >> 1;
163+
if (count(mid, k, nums) >= k) right = mid;
164+
else left = mid + 1;
165+
}
166+
return left;
167+
}
168+
169+
int count(int dist, int k, vector<int>& nums) {
170+
int cnt = 0;
171+
for (int i = 0; i < nums.size(); ++i)
172+
{
173+
int target = nums[i] - dist;
174+
int j = lower_bound(nums.begin(), nums.end(), target) - nums.begin();
175+
cnt += i - j;
176+
}
177+
return cnt;
178+
}
179+
};
180+
```
181+
182+
### **Go**
183+
184+
```go
185+
func smallestDistancePair(nums []int, k int) int {
186+
sort.Ints(nums)
187+
n := len(nums)
188+
left, right := 0, nums[n-1]-nums[0]
189+
count := func(dist int) int {
190+
cnt := 0
191+
for i, v := range nums {
192+
target := v - dist
193+
left, right := 0, i
194+
for left < right {
195+
mid := (left + right) >> 1
196+
if nums[mid] >= target {
197+
right = mid
198+
} else {
199+
left = mid + 1
200+
}
201+
}
202+
cnt += i - left
203+
}
204+
return cnt
205+
}
206+
for left < right {
207+
mid := (left + right) >> 1
208+
if count(mid) >= k {
209+
right = mid
210+
} else {
211+
left = mid + 1
212+
}
213+
}
214+
return left
215+
}
216+
```
217+
103218
### **...**
104219

105220
```

solution/0700-0799/0719.Find K-th Smallest Pair Distance/README_EN.md

Lines changed: 110 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,13 +52,56 @@ Then the 1<sup>st</sup> smallest distance pair is (1,1), and its distance is 0.
5252
### **Python3**
5353

5454
```python
55-
55+
class Solution:
56+
def smallestDistancePair(self, nums: List[int], k: int) -> int:
57+
def count(dist):
58+
cnt = 0
59+
for i, b in enumerate(nums):
60+
a = b - dist
61+
j = bisect_left(nums, a, 0, i)
62+
cnt += i - j
63+
return cnt
64+
65+
nums.sort()
66+
return bisect_left(range(nums[-1] - nums[0]), k, key=count)
5667
```
5768

5869
### **Java**
5970

6071
```java
72+
class Solution {
73+
public int smallestDistancePair(int[] nums, int k) {
74+
Arrays.sort(nums);
75+
int left = 0, right = nums[nums.length - 1] - nums[0];
76+
while (left < right) {
77+
int mid = (left + right) >> 1;
78+
if (count(mid, nums) >= k) {
79+
right = mid;
80+
} else {
81+
left = mid + 1;
82+
}
83+
}
84+
return left;
85+
}
6186

87+
private int count(int dist, int[] nums) {
88+
int cnt = 0;
89+
for (int i = 0; i < nums.length; ++i) {
90+
int left = 0, right = i;
91+
while (left < right) {
92+
int mid = (left + right) >> 1;
93+
int target = nums[i] - dist;
94+
if (nums[mid] >= target) {
95+
right = mid;
96+
} else {
97+
left = mid + 1;
98+
}
99+
}
100+
cnt += i - left;
101+
}
102+
return cnt;
103+
}
104+
}
62105
```
63106

64107
### **TypeScript**
@@ -74,7 +117,6 @@ function smallestDistancePair(nums: number[], k: number): number {
74117
let count = 0,
75118
i = 0;
76119
for (let j = 0; j < n; j++) {
77-
// 索引[i, j]距离nums[j]的距离<=mid
78120
while (nums[j] - nums[i] > mid) {
79121
i++;
80122
}
@@ -90,6 +132,72 @@ function smallestDistancePair(nums: number[], k: number): number {
90132
}
91133
```
92134

135+
### **C++**
136+
137+
```cpp
138+
class Solution {
139+
public:
140+
int smallestDistancePair(vector<int>& nums, int k) {
141+
sort(nums.begin(), nums.end());
142+
int left = 0, right = nums.back() - nums.front();
143+
while (left < right)
144+
{
145+
int mid = (left + right) >> 1;
146+
if (count(mid, k, nums) >= k) right = mid;
147+
else left = mid + 1;
148+
}
149+
return left;
150+
}
151+
152+
int count(int dist, int k, vector<int>& nums) {
153+
int cnt = 0;
154+
for (int i = 0; i < nums.size(); ++i)
155+
{
156+
int target = nums[i] - dist;
157+
int j = lower_bound(nums.begin(), nums.end(), target) - nums.begin();
158+
cnt += i - j;
159+
}
160+
return cnt;
161+
}
162+
};
163+
```
164+
165+
### **Go**
166+
167+
```go
168+
func smallestDistancePair(nums []int, k int) int {
169+
sort.Ints(nums)
170+
n := len(nums)
171+
left, right := 0, nums[n-1]-nums[0]
172+
count := func(dist int) int {
173+
cnt := 0
174+
for i, v := range nums {
175+
target := v - dist
176+
left, right := 0, i
177+
for left < right {
178+
mid := (left + right) >> 1
179+
if nums[mid] >= target {
180+
right = mid
181+
} else {
182+
left = mid + 1
183+
}
184+
}
185+
cnt += i - left
186+
}
187+
return cnt
188+
}
189+
for left < right {
190+
mid := (left + right) >> 1
191+
if count(mid) >= k {
192+
right = mid
193+
} else {
194+
left = mid + 1
195+
}
196+
}
197+
return left
198+
}
199+
```
200+
93201
### **...**
94202

95203
```
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
class Solution {
2+
public:
3+
int smallestDistancePair(vector<int>& nums, int k) {
4+
sort(nums.begin(), nums.end());
5+
int left = 0, right = nums.back() - nums.front();
6+
while (left < right)
7+
{
8+
int mid = (left + right) >> 1;
9+
if (count(mid, k, nums) >= k) right = mid;
10+
else left = mid + 1;
11+
}
12+
return left;
13+
}
14+
15+
int count(int dist, int k, vector<int>& nums) {
16+
int cnt = 0;
17+
for (int i = 0; i < nums.size(); ++i)
18+
{
19+
int target = nums[i] - dist;
20+
int j = lower_bound(nums.begin(), nums.end(), target) - nums.begin();
21+
cnt += i - j;
22+
}
23+
return cnt;
24+
}
25+
};
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
func smallestDistancePair(nums []int, k int) int {
2+
sort.Ints(nums)
3+
n := len(nums)
4+
left, right := 0, nums[n-1]-nums[0]
5+
count := func(dist int) int {
6+
cnt := 0
7+
for i, v := range nums {
8+
target := v - dist
9+
left, right := 0, i
10+
for left < right {
11+
mid := (left + right) >> 1
12+
if nums[mid] >= target {
13+
right = mid
14+
} else {
15+
left = mid + 1
16+
}
17+
}
18+
cnt += i - left
19+
}
20+
return cnt
21+
}
22+
for left < right {
23+
mid := (left + right) >> 1
24+
if count(mid) >= k {
25+
right = mid
26+
} else {
27+
left = mid + 1
28+
}
29+
}
30+
return left
31+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
class Solution {
2+
public int smallestDistancePair(int[] nums, int k) {
3+
Arrays.sort(nums);
4+
int left = 0, right = nums[nums.length - 1] - nums[0];
5+
while (left < right) {
6+
int mid = (left + right) >> 1;
7+
if (count(mid, nums) >= k) {
8+
right = mid;
9+
} else {
10+
left = mid + 1;
11+
}
12+
}
13+
return left;
14+
}
15+
16+
private int count(int dist, int[] nums) {
17+
int cnt = 0;
18+
for (int i = 0; i < nums.length; ++i) {
19+
int left = 0, right = i;
20+
while (left < right) {
21+
int mid = (left + right) >> 1;
22+
int target = nums[i] - dist;
23+
if (nums[mid] >= target) {
24+
right = mid;
25+
} else {
26+
left = mid + 1;
27+
}
28+
}
29+
cnt += i - left;
30+
}
31+
return cnt;
32+
}
33+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Solution:
2+
def smallestDistancePair(self, nums: List[int], k: int) -> int:
3+
def count(dist):
4+
cnt = 0
5+
for i, b in enumerate(nums):
6+
a = b - dist
7+
j = bisect_left(nums, a, 0, i)
8+
cnt += i - j
9+
return cnt
10+
11+
nums.sort()
12+
return bisect_left(range(nums[-1] - nums[0]), k, key=count)

0 commit comments

Comments
 (0)