LeetCode#164 | Nobilta's Blog
0%

LeetCode#164

LeetCode#164最大间距

题目链接
题意非常简单,给你一个无序的数组,让你对数组排序之后找到最大的相邻数之差。我啪的一下很快啊就敲了一个用sort排序,然后再遍历一遍数组得到了答案(
很明显这并不是正解,官方题解给出的答案是使用基数排序,那就记录一下如何进行基数排序吧。
基数排序(radix sort)属于“分配式排序”(distribution sort),又称“桶子法”(bucket sort)或bin sort,顾名思义,它是透过键值的部份资讯,将要排序的元素分配至某些“桶”中,藉以达到排序的作用,基数排序法是属于稳定性的排序,其时间复杂度为O (nlog(r)m),其中r为所采取的基数,而m为堆数,在某些时候,基数排序法的效率高于其它的稳定性排序法。(百度百科
举个简单的例子:使用基数排序对73, 22, 93, 43, 55, 14, 28, 65, 39, 81进行排序:
比如我们可以使用10个桶,先对它们的个位进行排序:

1
2
3
4
5
6
7
8
9
10
0:
1:81
2:22
3:73 93 43
4:14
5:55
6:
7:
8:28
9:39

然后是按照十位进行排序:

1
2
3
4
5
6
7
8
9
10
0:
1:14
2:22 28
3:39
4:43
5:55
6:65
7:73
8:81
9:93

将两次排序的结果进行合并,我们就能得到结果了:14 22 28 39 43 55 65 73 81 93
如果数组中有三位数乃至n位数,我们只需要继续进行排序,直到全部位置都遍历完。
回到这个题,我们使用基数排序就可以这样写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
class Solution {
public:
int maximumGap(vector<int>& nums) {
int n = nums.size();
if (n < 2) {
return 0;
}
int exp = 1;
vector<int> buf(n);
int maxVal = *max_element(nums.begin(), nums.end());

while (maxVal >= exp) {
vector<int> cnt(10);
for (int i = 0; i < n; i++) {
int digit = (nums[i] / exp) % 10;
cnt[digit]++;
}
for (int i = 1; i < 10; i++) {
cnt[i] += cnt[i - 1];
}
for (int i = n - 1; i >= 0; i--) {
int digit = (nums[i] / exp) % 10;
buf[cnt[digit] - 1] = nums[i];
cnt[digit]--;
}
copy(buf.begin(), buf.end(), nums.begin());
exp *= 10;
}

int ret = 0;
for (int i = 1; i < n; i++) {
ret = max(ret, nums[i] - nums[i - 1]);
}
return ret;
}
};

(使用基数排序结果反而比用sort慢。。。。果然人家写好的现成的就是比自己写的强啊

您的支持将鼓励我继续创作!