Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 03deb8c

Browse files
committed
feat: add solutions to lc problem: No.0164
No.0164.Maximum Gap
1 parent 853a54d commit 03deb8c

File tree

6 files changed

+540
-8
lines changed

6 files changed

+540
-8
lines changed

‎solution/0100-0199/0164.Maximum Gap/README.md‎

Lines changed: 215 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,22 +39,236 @@
3939

4040
<!-- 这里可写通用的实现逻辑 -->
4141

42+
**前言**
43+
44+
一种容易想到的解法是将数组排序后得到相邻元素之间最大的差值,时间复杂度 $O(n \log n),ドル不符合题目要求。
45+
46+
只有使用不基于比较的的排序算法才能在线性时间复杂度解决。
47+
48+
**方法一:桶排序**
49+
50+
假设数组 $nums$ 有 $n$ 个元素,所有元素从小到大依次是 $nums_0$ 到 $nums_{n - 1},ドル最大间距是 $maxGap$。考虑数组中的最大元素和最小元素之差。
51+
52+
$$
53+
nums_{n - 1} - nums_0 = \sum_{i = 1}^{n - 1} (nums_i - nums_{i - 1}) \le{maxGap} \times (n - 1)
54+
$$
55+
56+
因此 $maxGap \ge \dfrac{nums_{n - 1} - nums_0}{n - 1},ドル即最大间距至少为 $\dfrac{nums_{n - 1} - nums_0}{n - 1}$。
57+
58+
可以利用桶排序的思想,设定桶的大小(即每个桶最多包含的不同元素个数)为 $\dfrac{nums_{n - 1} - nums_0}{n - 1},ドル将元素按照元素值均匀分布到各个桶内,则同一个桶内的任意两个元素之差小于 ${maxGap},ドル差为 ${maxGap}$ 的两个元素一定在两个不同的桶内。对于每个桶,维护桶内的最小值和最大值,初始时每个桶内的最小值和最大值分别是正无穷和负无穷,表示桶内没有元素。
59+
60+
遍历数组 ${nums}$ 中的所有元素。对于每个元素,根据该元素与最小元素之差以及桶的大小计算该元素应该分到的桶的编号,可以确保编号小的桶内的元素都小于编号大的桶内的元素,使用元素值更新元素所在的桶内的最小值和最大值。
61+
62+
遍历数组结束之后,每个非空的桶内的最小值和最大值都可以确定。按照桶的编号从小到大的顺序依次遍历每个桶,当前的桶的最小值和上一个非空的桶的最大值是排序后的相邻元素,计算两个相邻元素之差,并更新最大间距。遍历桶结束之后即可得到最大间距。
63+
64+
时间复杂度 $O(n),ドル空间复杂度 $O(n)$。
65+
4266
<!-- tabs:start -->
4367

4468
### **Python3**
4569

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

4872
```python
49-
73+
class Solution:
74+
def maximumGap(self, nums: List[int]) -> int:
75+
n = len(nums)
76+
if n < 2:
77+
return 0
78+
mi, mx = min(nums), max(nums)
79+
bucket_size = max(1, (mx - mi) // (n - 1))
80+
bucket_count = (mx - mi) // bucket_size + 1
81+
buckets = [[inf, -inf] for _ in range(bucket_count)]
82+
for v in nums:
83+
i = (v - mi) // bucket_size
84+
buckets[i][0] = min(buckets[i][0], v)
85+
buckets[i][1] = max(buckets[i][1], v)
86+
ans = 0
87+
prev = inf
88+
for curmin, curmax in buckets:
89+
if curmin > curmax:
90+
continue
91+
ans = max(ans, curmin - prev)
92+
prev = curmax
93+
return ans
5094
```
5195

5296
### **Java**
5397

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

56100
```java
101+
class Solution {
102+
public int maximumGap(int[] nums) {
103+
int n = nums.length;
104+
if (n < 2) {
105+
return 0;
106+
}
107+
int inf = 0x3f3f3f3f;
108+
int mi = inf, mx = -inf;
109+
for (int v : nums) {
110+
mi = Math.min(mi, v);
111+
mx = Math.max(mx, v);
112+
}
113+
int bucketSize = Math.max(1, (mx - mi) / (n - 1));
114+
int bucketCount = (mx - mi) / bucketSize + 1;
115+
int[][] buckets = new int[bucketCount][2];
116+
for (var bucket : buckets) {
117+
bucket[0] = inf;
118+
bucket[1] = -inf;
119+
}
120+
for (int v : nums) {
121+
int i = (v - mi) / bucketSize;
122+
buckets[i][0] = Math.min(buckets[i][0], v);
123+
buckets[i][1] = Math.max(buckets[i][1], v);
124+
}
125+
int prev = inf;
126+
int ans = 0;
127+
for (var bucket : buckets) {
128+
if (bucket[0] > bucket[1]) {
129+
continue;
130+
}
131+
ans = Math.max(ans, bucket[0] - prev);
132+
prev = bucket[1];
133+
}
134+
return ans;
135+
}
136+
}
137+
```
138+
139+
### **C++**
140+
141+
```cpp
142+
using pii = pair<int, int>;
143+
144+
class Solution {
145+
public:
146+
const int inf = 0x3f3f3f3f;
147+
int maximumGap(vector<int>& nums) {
148+
int n = nums.size();
149+
if (n < 2) return 0;
150+
int mi = inf, mx = - inf;
151+
for (int v : nums)
152+
{
153+
mi = min(mi, v);
154+
mx = max(mx, v);
155+
}
156+
int bucketSize = max(1, (mx - mi) / (n - 1));
157+
int bucketCount = (mx - mi) / bucketSize + 1;
158+
vector<pii> buckets(bucketCount, {inf, -inf});
159+
for (int v : nums)
160+
{
161+
int i = (v - mi) / bucketSize;
162+
buckets[i].first = min(buckets[i].first, v);
163+
buckets[i].second = max(buckets[i].second, v);
164+
}
165+
int ans = 0;
166+
int prev = inf;
167+
for (auto [curmin, curmax] : buckets)
168+
{
169+
if (curmin > curmax) continue;
170+
ans = max(ans, curmin - prev);
171+
prev = curmax;
172+
}
173+
return ans;
174+
}
175+
};
176+
```
177+
178+
### **Go**
179+
180+
```go
181+
func maximumGap(nums []int) int {
182+
n := len(nums)
183+
if n < 2 {
184+
return 0
185+
}
186+
inf := 0x3f3f3f3f
187+
mi, mx := inf, -inf
188+
for _, v := range nums {
189+
mi = min(mi, v)
190+
mx = max(mx, v)
191+
}
192+
bucketSize := max(1, (mx-mi)/(n-1))
193+
bucketCount := (mx-mi)/bucketSize + 1
194+
buckets := make([][]int, bucketCount)
195+
for i := range buckets {
196+
buckets[i] = []int{inf, -inf}
197+
}
198+
for _, v := range nums {
199+
i := (v - mi) / bucketSize
200+
buckets[i][0] = min(buckets[i][0], v)
201+
buckets[i][1] = max(buckets[i][1], v)
202+
}
203+
ans := 0
204+
prev := inf
205+
for _, bucket := range buckets {
206+
if bucket[0] > bucket[1] {
207+
continue
208+
}
209+
ans = max(ans, bucket[0]-prev)
210+
prev = bucket[1]
211+
}
212+
return ans
213+
}
214+
215+
func min(a, b int) int {
216+
if a < b {
217+
return a
218+
}
219+
return b
220+
}
221+
222+
func max(a, b int) int {
223+
if a > b {
224+
return a
225+
}
226+
return b
227+
}
228+
```
229+
230+
### **C#**
231+
232+
```cs
233+
using System;
234+
using System.Linq;
235+
236+
public class Solution {
237+
public int MaximumGap(int[] nums) {
238+
if (nums.Length < 2) return 0;
239+
var max = nums.Max();
240+
var min = nums.Min();
241+
var bucketSize = Math.Max(1, (max - min) / (nums.Length - 1));
242+
var buckets = new Tuple<int, int>[(max - min) / bucketSize + 1];
243+
foreach (var num in nums)
244+
{
245+
var index = (num - min) / bucketSize;
246+
if (buckets[index] == null)
247+
{
248+
buckets[index] = Tuple.Create(num, num);
249+
}
250+
else
251+
{
252+
buckets[index] = Tuple.Create(Math.Min(buckets[index].Item1, num), Math.Max(buckets[index].Item2, num));
253+
}
254+
}
57255

256+
var result = 0;
257+
Tuple<int, int> lastBucket = null;
258+
for (var i = 0; i < buckets.Length; ++i)
259+
{
260+
if (buckets[i] != null)
261+
{
262+
if (lastBucket != null)
263+
{
264+
result = Math.Max(result, buckets[i].Item1 - lastBucket.Item2);
265+
}
266+
lastBucket = buckets[i];
267+
}
268+
}
269+
return result;
270+
}
271+
}
58272
```
59273

60274
### **...**

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /