Algorithm算法杂谈 有趣的排序思想

计数排序

应用场景:简单的单值排序问题,排序问题中的数据的值域很有限

基数排序

  • 对个位计数
  • 求前缀和(求区域尾坐标)
  • 归位
  • 对十位计数
  • 归位

数据特性:保证数据的稳定性

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);
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值