计数排序
应用场景:简单的单值排序问题,排序问题中的数据的值域很有限
基数排序
- 对个位计数
- 求前缀和(求区域尾坐标)
- 归位
- 对十位计数
- 归位
数据特性:保证数据的稳定性
void radix_sort(int *arr, int n){
int cnt[65536] = {0};
int *temp = (int *)malloc(sizeof(int)* n);
// low 16 bit sort
for(int i = 0; i < n; i++) cnt[arr[i]] & 0xffff] += 1; // count
for(int i = 0; i < 65536; i++) cnt[i] += cnt[i - 1]; // prefix sum
for(int i = n - 1; i >= 0; --i) temp[--cnt[arr[i] & 0xffff]] = arr[i]; // placement
// init cnt;
for(int i = 0; i < 65536; i++) cnt[i] = 0;
// high 16 bit sort
for(int i = 0; i < n; i++) cnt[temp[i] & 0xffff0000] += 1 // count
for(int i = 0; i < n; i++) cnt[i] += cnt[i -1]; // prefix sum
for(int i = n - 1; i >= 0; --i) arr[--cnt[temp[i] & 0xffff0000]] = temp[i]; //placement
free(temp);
return ;
}
拓扑排序
对有向图进行依赖关系的排序
经典面试题 - 基础排序思想
1122. 数组的相对排序
- 计数排序
class Solution {
public:
vector<int> relativeSortArray(vector<int>& arr1, vector<int>& arr2) {
int cnt[1005] = {0};
for(auto x: arr1) cnt[x] += 1;
int k = 0;
for(auto x: arr2){
for(int i = 0; i < cnt[x]; i++){
arr1[k++] = x;
}
cnt[x] = 0;
}
for(int i = 0; i< 1001; i++){
if(cnt[i] == 0) continue;
for(int j = 0; j < cnt[i]; j++) arr1[k++] = i;
}
return arr1;
}
};
164. 最大间距
class Solution {
public:
int maximumGap(vector<int>& nums) {
int cnt[65536] = {0};
vector<int> temp(nums.size());
for(auto x: nums) cnt[x & 0xffff] += 1;
for(int i = 1; i< 65536; i++) cnt[i] += cnt[i - 1];
for(int i = nums.size() - 1; i >= 0; --i) temp[--cnt[nums[i] % 65536 ]] = nums[i];
memset(cnt, 0, sizeof(cnt));
for(auto x: temp) cnt[x / 65536] += 1;
for(int i = 1; i< 65536; i++) cnt[i] += cnt[i - 1];
for(int i = temp.size() - 1; i >= 0; --i) nums[--cnt[temp[i] / 65536 ]] = temp[i];
int ans = 0;
for(int i = 1; i < nums.size(); i++){
ans = max(ans, nums[i] - nums[i - 1]);
}
return ans;
}
};
274. H 指数
class Solution {
public:
int hIndex(vector<int>& citations) {
sort(citations.begin(), citations.end());
int h = 1, n = citations.size();
while(h <= n && citations[n - h] >= h) ++h;
h -= 1;
return h;
}
};
207. 课程表
class Solution {
public:
bool canFinish(int numCourses, vector<vector<int>>& prerequisites) {
int indeg[numCourses];
memset(indeg, 0, sizeof(indeg));
vector<vector<int>> g(numCourses);
queue<int> q;
for(auto x: prerequisites){
indeg[x[0]] += 1;
g[x[1]].push_back(x[0]);
}
for(int i = 0; i < numCourses; i++){
if(indeg[i] == 0) q.push(i);
}
int cnt = 0;
while(!q.empty()){
int ind = q.front();
q.pop(); cnt += 1;
for(auto to: g[ind]){
indeg[to] -= 1;
if(indeg[to] == 0) q.push(to);
}
}
return cnt == numCourses;
}
};
210. 课程表 II
class Solution {
public:
vector<int> findOrder(int numCourses, vector<vector<int>>& prerequisites) {
int indeg[numCourses];
memset(indeg, 0, sizeof(indeg));
vector<vector<int>> g(numCourses);
queue<int> q;
for(auto x: prerequisites){
indeg[x[0]] += 1;
g[x[1]].push_back(x[0]);
}
for(int i = 0; i < numCourses; i++){
if(indeg[i] == 0) q.push(i);
}
vector<int> ans;
while(!q.empty()){
int ind = q.front();
q.pop(); ans.push_back(ind);
for(auto to: g[ind]){
indeg[to] -= 1;
if(indeg[to] == 0) q.push(to);
}
}
if(ans.size() == numCourses) return ans;
return vector<int>();
}
};
56.合并区间
class Solution {
public:
vector<vector<int>> merge(vector<vector<int>>& intervals) {
vector<vector<int>> arr;
vector<int> temp(2);
for(auto x : intervals){
temp[0] = x[0];
temp[1] = 1;
arr.push_back(temp);
temp[0] = x[1];
temp[1] = -1;
arr.push_back(temp);
}
sort(arr.begin(), arr.end(),
[](const vector<int> &a, const vector<int> &b)->bool{
if(a[0] - b[0]) return a[0] < b[0];
return a[1] > b[1];
}
);
int pre = -1, sum = 0;
vector<vector<int>> ret;
for(int i = 0; i < arr.size(); i++){
if(pre == -1) pre = arr[i][0];
sum += arr[i][1];
if(sum == 0){
temp[0] = pre;
temp[1] = arr[i][0];
ret.push_back(temp);
pre = -1;
}
}
return ret;
}
};
1288. 删除被覆盖区间
class Solution {
public:
int removeCoveredIntervals(vector<vector<int>>& intervals) {
sort(intervals.begin(), intervals.end(),
[](const vector<int> &a, const vector<int> &b)->bool{
if(a[0] - b[0]) return a[0] < b[0];
return a[1] > b[1];
}
);
int cnt = 0, pre = -1;
for(auto x: intervals){
if(pre >= x[1]) cnt += 1;
pre = max(x[1], pre);
}
return intervals.size() - cnt;
}
};
491. 递增子序列
class Solution {
public:
void getResult(vector<int> &nums, int k, vector<int> buff, vector<vector<int>> &ret){
if(buff.size() > 1) ret.push_back(buff);
buff.push_back(0);
unordered_map<int, int> can;
for(int i = k; i < nums.size(); i++){
if(can.find(nums[i]) != can.end()) continue;
if(buff.size() == 1 || nums[i] >= buff[buff.size() - 2]){
buff[buff.size() - 1] = nums[i];
can[nums[i]] = 1;
getResult(nums, i + 1, buff, ret);
}
}
return;
}
vector<vector<int>> findSubsequences(vector<int>& nums) {
vector<vector<int>> ret;
getResult(nums, 0, vector<int>(), ret);
return ret;
}
};
面试题 04.12. 求和路径
class Solution {
public:
int getPathSum(TreeNode *root, int sum){
if(root == NULL) return 0;
int val = root->val;
return (val == sum) + getPathSum(root->left, sum - val) + getPathSum(root->right, sum - val);
}
int pathSum(TreeNode* root, int sum) {
if(root == NULL) return 0;
int a = getPathSum(root, sum);
return a + pathSum(root->left, sum) + pathSum(root->right, sum);
}
};