Skip to content

Commit 4250319

Browse files
committed
feat: add solutions to lc problem: No.1637
No.1637.Widest Vertical Area Between Two Points Containing No Points
1 parent 0212990 commit 4250319

File tree

8 files changed

+613
-22
lines changed

8 files changed

+613
-22
lines changed

solution/1600-1699/1637.Widest Vertical Area Between Two Points Containing No Points/README.md

Lines changed: 240 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,31 @@
4646

4747
**方法一:排序**
4848

49-
我们可以对 `points` 按照 $x$ 升序排列,获取相邻点之间 $x$ 的差值的最大值。
49+
我们可以对数组 $points$ 按照 $x$ 升序排列,获取相邻点之间 $x$ 的差值的最大值。
5050

51-
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为 `points` 的长度。
51+
时间复杂度 $O(n \times \log n)$,空间复杂度 $O(\log n)$。其中 $n$ 为数组 $points$ 的长度。
52+
53+
**方法二:桶排序**
54+
55+
方法一中排序的时间复杂度为 $O(n \times \log n)$,其实我们可以利用桶排序的思想,将时间复杂度降低到 $O(n)$。
56+
57+
我们将数组 $points$ 的横坐标放入数组 $nums$ 中。
58+
59+
假设数组 $nums$ 有 $n$ 个元素,所有元素从小到大依次是 $nums_0$ 到 $nums_{n - 1}$,最大间距是 $maxGap$。考虑数组中的最大元素和最小元素之差:
60+
61+
$$
62+
nums_{n - 1} - nums_0 = \sum_{i = 1}^{n - 1} (nums_i - nums_{i - 1}) \le{maxGap} \times (n - 1)
63+
$$
64+
65+
因此 $maxGap \ge \dfrac{nums_{n - 1} - nums_0}{n - 1}$,即最大间距至少为 $\dfrac{nums_{n - 1} - nums_0}{n - 1}$。
66+
67+
可以利用桶排序的思想,设定桶的大小(即每个桶最多包含的不同元素个数)为 $\dfrac{nums_{n - 1} - nums_0}{n - 1}$,将元素按照元素值均匀分布到各个桶内,则同一个桶内的任意两个元素之差小于 ${maxGap}$,差为 ${maxGap}$ 的两个元素一定在两个不同的桶内。对于每个桶,维护桶内的最小值和最大值,初始时每个桶内的最小值和最大值分别是正无穷和负无穷,表示桶内没有元素。
68+
69+
遍历数组 ${nums}$ 中的所有元素。对于每个元素,根据该元素与最小元素之差以及桶的大小计算该元素应该分到的桶的编号,可以确保编号小的桶内的元素都小于编号大的桶内的元素,使用元素值更新元素所在的桶内的最小值和最大值。
70+
71+
遍历数组结束之后,每个非空的桶内的最小值和最大值都可以确定。按照桶的编号从小到大的顺序依次遍历每个桶,当前的桶的最小值和上一个非空的桶的最大值是排序后的相邻元素,计算两个相邻元素之差,并更新最大间距。遍历桶结束之后即可得到最大间距。
72+
73+
时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 为数组 $points$ 的长度。
5274

5375
<!-- tabs:start -->
5476

@@ -63,6 +85,29 @@ class Solution:
6385
return max(b[0] - a[0] for a, b in pairwise(points))
6486
```
6587

88+
```python
89+
class Solution:
90+
def maxWidthOfVerticalArea(self, points: List[List[int]]) -> int:
91+
nums = [x for x, _ in points]
92+
n = len(nums)
93+
mi, mx = min(nums), max(nums)
94+
bucket_size = max(1, (mx - mi) // (n - 1))
95+
bucket_count = (mx - mi) // bucket_size + 1
96+
buckets = [[inf, -inf] for _ in range(bucket_count)]
97+
for x in nums:
98+
i = (x - mi) // bucket_size
99+
buckets[i][0] = min(buckets[i][0], x)
100+
buckets[i][1] = max(buckets[i][1], x)
101+
ans = 0
102+
prev = inf
103+
for curmin, curmax in buckets:
104+
if curmin > curmax:
105+
continue
106+
ans = max(ans, curmin - prev)
107+
prev = curmax
108+
return ans
109+
```
110+
66111
### **Java**
67112

68113
<!-- 这里可写当前语言的特殊实现逻辑 -->
@@ -80,6 +125,46 @@ class Solution {
80125
}
81126
```
82127

128+
```java
129+
class Solution {
130+
public int maxWidthOfVerticalArea(int[][] points) {
131+
int n = points.length;
132+
int[] nums = new int[n];
133+
for (int i = 0; i < n; ++i) {
134+
nums[i] = points[i][0];
135+
}
136+
final int inf = 1 << 30;
137+
int mi = inf, mx = -inf;
138+
for (int v : nums) {
139+
mi = Math.min(mi, v);
140+
mx = Math.max(mx, v);
141+
}
142+
int bucketSize = Math.max(1, (mx - mi) / (n - 1));
143+
int bucketCount = (mx - mi) / bucketSize + 1;
144+
int[][] buckets = new int[bucketCount][2];
145+
for (var bucket : buckets) {
146+
bucket[0] = inf;
147+
bucket[1] = -inf;
148+
}
149+
for (int v : nums) {
150+
int i = (v - mi) / bucketSize;
151+
buckets[i][0] = Math.min(buckets[i][0], v);
152+
buckets[i][1] = Math.max(buckets[i][1], v);
153+
}
154+
int prev = inf;
155+
int ans = 0;
156+
for (var bucket : buckets) {
157+
if (bucket[0] > bucket[1]) {
158+
continue;
159+
}
160+
ans = Math.max(ans, bucket[0] - prev);
161+
prev = bucket[1];
162+
}
163+
return ans;
164+
}
165+
}
166+
```
167+
83168
### **C++**
84169

85170
```cpp
@@ -96,6 +181,41 @@ public:
96181
};
97182
```
98183
184+
```cpp
185+
class Solution {
186+
public:
187+
int maxWidthOfVerticalArea(vector<vector<int>>& points) {
188+
int n = points.size();
189+
vector<int> nums;
190+
for (auto& p : points) {
191+
nums.push_back(p[0]);
192+
}
193+
const int inf = 1 << 30;
194+
int mi = inf, mx = -inf;
195+
for (int v : nums) {
196+
mi = min(mi, v);
197+
mx = max(mx, v);
198+
}
199+
int bucketSize = max(1, (mx - mi) / (n - 1));
200+
int bucketCount = (mx - mi) / bucketSize + 1;
201+
vector<pair<int, int>> buckets(bucketCount, {inf, -inf});
202+
for (int v : nums) {
203+
int i = (v - mi) / bucketSize;
204+
buckets[i].first = min(buckets[i].first, v);
205+
buckets[i].second = max(buckets[i].second, v);
206+
}
207+
int ans = 0;
208+
int prev = inf;
209+
for (auto [curmin, curmax] : buckets) {
210+
if (curmin > curmax) continue;
211+
ans = max(ans, curmin - prev);
212+
prev = curmax;
213+
}
214+
return ans;
215+
}
216+
};
217+
```
218+
99219
### **Go**
100220

101221
```go
@@ -115,6 +235,56 @@ func max(a, b int) int {
115235
}
116236
```
117237

238+
```go
239+
func maxWidthOfVerticalArea(points [][]int) (ans int) {
240+
n := len(points)
241+
nums := make([]int, 0, n)
242+
for _, p := range points {
243+
nums = append(nums, p[0])
244+
}
245+
const inf = 1 << 30
246+
mi, mx := inf, -inf
247+
for _, v := range nums {
248+
mi = min(mi, v)
249+
mx = max(mx, v)
250+
}
251+
bucketSize := max(1, (mx-mi)/(n-1))
252+
bucketCount := (mx-mi)/bucketSize + 1
253+
buckets := make([][]int, bucketCount)
254+
for i := range buckets {
255+
buckets[i] = []int{inf, -inf}
256+
}
257+
for _, v := range nums {
258+
i := (v - mi) / bucketSize
259+
buckets[i][0] = min(buckets[i][0], v)
260+
buckets[i][1] = max(buckets[i][1], v)
261+
}
262+
prev := inf
263+
for _, bucket := range buckets {
264+
if bucket[0] > bucket[1] {
265+
continue
266+
}
267+
ans = max(ans, bucket[0]-prev)
268+
prev = bucket[1]
269+
}
270+
return ans
271+
}
272+
273+
func min(a, b int) int {
274+
if a < b {
275+
return a
276+
}
277+
return b
278+
}
279+
280+
func max(a, b int) int {
281+
if a > b {
282+
return a
283+
}
284+
return b
285+
}
286+
```
287+
118288
### **TypeScript**
119289

120290
```ts
@@ -128,6 +298,38 @@ function maxWidthOfVerticalArea(points: number[][]): number {
128298
}
129299
```
130300

301+
```ts
302+
function maxWidthOfVerticalArea(points: number[][]): number {
303+
const nums: number[] = points.map(point => point[0]);
304+
const inf = 1 << 30;
305+
const n = nums.length;
306+
let mi = inf;
307+
let mx = -inf;
308+
for (const x of nums) {
309+
mi = Math.min(mi, x);
310+
mx = Math.max(mx, x);
311+
}
312+
const bucketSize = Math.max(1, Math.floor((mx - mi) / (n - 1)));
313+
const bucketCount = Math.floor((mx - mi) / bucketSize) + 1;
314+
const buckets = new Array(bucketCount).fill(0).map(() => [inf, -inf]);
315+
for (const x of nums) {
316+
const i = Math.floor((x - mi) / bucketSize);
317+
buckets[i][0] = Math.min(buckets[i][0], x);
318+
buckets[i][1] = Math.max(buckets[i][1], x);
319+
}
320+
let prev = inf;
321+
let ans = 0;
322+
for (const [left, right] of buckets) {
323+
if (left > right) {
324+
continue;
325+
}
326+
ans = Math.max(ans, left - prev);
327+
prev = right;
328+
}
329+
return ans;
330+
}
331+
```
332+
131333
### **JavaScript**
132334

133335
```js
@@ -147,6 +349,42 @@ var maxWidthOfVerticalArea = function (points) {
147349
};
148350
```
149351

352+
```js
353+
/**
354+
* @param {number[][]} points
355+
* @return {number}
356+
*/
357+
var maxWidthOfVerticalArea = function (points) {
358+
const nums = points.map(point => point[0]);
359+
const inf = 1 << 30;
360+
const n = nums.length;
361+
let mi = inf;
362+
let mx = -inf;
363+
for (const x of nums) {
364+
mi = Math.min(mi, x);
365+
mx = Math.max(mx, x);
366+
}
367+
const bucketSize = Math.max(1, Math.floor((mx - mi) / (n - 1)));
368+
const bucketCount = Math.floor((mx - mi) / bucketSize) + 1;
369+
const buckets = new Array(bucketCount).fill(0).map(() => [inf, -inf]);
370+
for (const x of nums) {
371+
const i = Math.floor((x - mi) / bucketSize);
372+
buckets[i][0] = Math.min(buckets[i][0], x);
373+
buckets[i][1] = Math.max(buckets[i][1], x);
374+
}
375+
let prev = inf;
376+
let ans = 0;
377+
for (const [left, right] of buckets) {
378+
if (left > right) {
379+
continue;
380+
}
381+
ans = Math.max(ans, left - prev);
382+
prev = right;
383+
}
384+
return ans;
385+
};
386+
```
387+
150388
### **...**
151389

152390
```

0 commit comments

Comments
 (0)