ref : Bucket Sort form GeeksforGeeks
ref : Bucket Sort from Leetcode
把目標數字分散在幾個桶子裡面,對每個桶子進行排序,最後依序取出數字,即為排序後的結果。
vector<int>& nums;
auto [mn, mx] = minmax_element(begin(nums), end(nums));
int shift = *mn, range = (*mx - *mn) / k;
vector<vector<int>> buckets(k, vector<int>());
for(auto& n : nums) {
int idx = (n - shift) / range;
buckets[idx].push_back(n);
}
for(auto& vec : buckets)
sort(vec.begin(), vec.end());
int idx = 0;
for(auto& vec : buckets) {
for(auto& n : vec) {
nums[idx++] = n;
}
}
worst case : 全部的數值都在同一個bucket,
等於沒分類的效果,就是看你的sort algoritm,最壞情況是\(O(N^2)\)
best case : 每個bucket都只有一個element,不需要對每個bucket做sort,所以分配element:\(O(N)\),把bucket內容組合起來\(O(K)\),所以best case是\(O(N+K)\)
Best | Average | Worst | |
---|---|---|---|
Bucket Sort | \(O(N+K)\) | \(O(N+K)\) | \(O(N^2)\) |
需要額外的空間儲放所有的element,所以\(O(N)\)
給你一個vector<int> nums, 找出index差小於等於k,且數字差小於等於t。
\(abs(num[i] - nums[j]) <= t\) 且 \(abs(i - j) <= k\)。
- 看到index差小於等於k,就會想到使用sliding window用兩個指標來代表window的前後。
- 重點是window裡面的資料怎麼排列?
- 因為兩個數的差小於等於t,可以使用bucket sort,每個bucket裡面的數字差一定小於等於t。
- bucket裡面不會有兩個以上的數字,因為只要是兩個就會成立離開。
- 還要跟前後的bucket去比較
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
int sz = nums.size();
unordered_map<int, int> m;
for(int i = 0, j = 0; i < sz; ++i) {
// 計算bucket,因為t有可能為INT_MAX,所以轉成long
int b = nums[i] / ((long)t + 1);
// 因為負數也會有0的情況
if(nums[i] < 0) b--;
// 兩個數在同一個bucket,符合情況。
if(m.count(b)) return true;
// 檢查後一個bucket
if(m.count(b + 1) && (long)m[b + 1] - nums[i] <= t) return true;
// 檢查前一個bucket
if(m.count(b - 1) && (long)nums[i] - m[b - 1] <= t) return true;
// 把資料放入bucket
m[b] = nums[i];
// 移除超出範圍的數字
if(i - j == k) {
int bj = nums[j] / ((long)t + 1);
if(nums[j] < 0) bj--;
m.erase(bj);
j++;
}
}
return false;
}
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int, int> freq; // value, count
for(auto& n : nums) freq[n]++; // O(N)
// create buckets, 因為最多出現次數為nums.size()
vector<vector<int>> buckets(nums.size() + 1, vector<int>());
for(auto& ref : freq)
buckets[ref.second].push_back(ref.first); //O(N)
vector<int> rtn; // O(K)
for(int i = buckets.size() - 1; i >= 0; --i) {
for(auto& n : buckets[i]) {
rtn.push_back(n);
k--;
if(k == 0) return rtn;
}
}
// time : O(N+N+K) = O(2N+K) = O(N+K)
// space : O(N+N) = O(2N) = O(N)
return {};
}
leetcode
刷題
or
or
By clicking below, you agree to our terms of service.
New to HackMD? Sign up
Syntax | Example | Reference | |
---|---|---|---|
# Header | Header | 基本排版 | |
- Unordered List |
|
||
1. Ordered List |
|
||
- [ ] Todo List |
|
||
> Blockquote | Blockquote |
||
**Bold font** | Bold font | ||
*Italics font* | Italics font | ||
~~Strikethrough~~ | |||
19^th^ | 19th | ||
H~2~O | H2O | ||
++Inserted text++ | Inserted text | ||
==Marked text== | Marked text | ||
[link text](https:// "title") | Link | ||
 | Image | ||
`Code` | Code |
在筆記中貼入程式碼 | |
```javascript var i = 0; ``` |
|
||
:smile: | ![]() |
Emoji list | |
{%youtube youtube_id %} | Externals | ||
$L^aT_eX$ | LaTeX | ||
:::info This is a alert area. ::: |
This is a alert area. |
On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?
Please give us some advice and help us improve HackMD.
Syncing