• “人活着就是为了贪心”——贪心算法日


    406. 根据身高重建队列

    假设有打乱顺序的一群人站成一个队列。 每个人由一个整数对(h, k)表示,其中h是这个人的身高,k是排在这个人前面且身高大于或等于h的人数。 编写一个算法来重建这个队列。

    注意:
    总人数少于1100人。

    示例

    输入:
    [[7,0], [4,4], [7,1], [5,0], [6,1], [5,2]]
    
    输出:
    [[5,0], [7,0], [5,2], [6,1], [4,4], [7,1]]
    

    由于身高矮的人对于身高高的人是不可见的,我们可以从高到矮依次按下标位置插入数据

    vector<vector<int>> reconstructQueue(vector<vector<int>>& people) {
            sort(people.begin(),people.end(),[](vector<int>& a,vector<int>& b){
                if(a[0]==b[0])return a[1]<b[1];
                return a[0]>b[0];
            });
            vector<vector<int>> arr;
            for(auto& p:people){
                arr.insert(arr.begin()+p[1],p);
            }
            return arr;
        }

    402. 移掉K位数字

    给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小。

    注意:

    ·num 的长度小于 10002 且 ≥ k。
    ·num 不会包含任何前导零。

    若有一个三位数abc,去掉一位

    ·a<b>c时 显然应该去掉b

    ·a<b<c时 显然要去掉c

    ·a>b<c时 ab ac bc 中显然bc最小

    所以我们每次要去掉字符串从头开始升序的最后一个字符

    方法一:直接对字符串遍历k次,在原字符串的基础上修改:

    void cut(string& num){
            int i=1;
            for(i=1;i<num.size();i++){
                if(num[i]>=num[i-1])continue;
                else break;
            }
            num.erase(num.begin()+i-1);
            i=0;
            while(i<num.length()&&num[i]=='0'){num.erase(num.begin());}
        }
        string removeKdigits(string num, int k) {
            string res="";
            if(num.length()<=k)return "0";
            while(k--){
                cut(num);
                if(num.length()==0)return "0";
            }
            return num;
        }

    方法二:维护一个最小栈

    class Solution {
    public:
        string removeKdigits(string num, int k) {
            stack<char> st;
            for(int i=0;i<num.length();i++){
                if(st.empty()||k==0){
                    if(!(st.empty()&&num[i]=='0'))
                        st.push(num[i]);
                }
                else{
                    if(num[i]>=st.top())st.push(num[i]);
                    else{
                        while(k&&!st.empty()&&num[i]<st.top()){
                            st.pop();k--;
                        }
                        i--;
                    }
                }
            }
            while(k--&&!st.empty())st.pop();
            if(st.empty())return "0";
            string res="";
            while(!st.empty()){
                res+=st.top();st.pop();
            }
            reverse(res.begin(),res.end());
            return res;
        }
    };

    1282. 用户分组

    有 n 位用户参加活动,他们的 ID 从 0 到 n - 1,每位用户都 恰好 属于某一用户组。给你一个长度为 n 的数组 groupSizes,其中包含每位用户所处的用户组的大小,请你返回用户分组情况(存在的用户组以及每个组中用户的 ID)。

    你可以任何顺序返回解决方案,ID 的顺序也不受限制。此外,题目给出的数据保证至少存在一种解决方案。

    按组内人数分组编号,组内人数相同的都放在一组,直到这个组满,然后放下一组

    class Solution {
    public:
        vector<vector<int>> groupThePeople(vector<int>& groupSizes) {
            unordered_map<int, int> sizeToId;
            int id=0;
            vector<vector<int>> ans;
            for(int i=0;i<groupSizes.size();i++){
                int num=groupSizes[i];
                if(sizeToId.count(num)==0||ans[sizeToId[num]].size()==num){
                    sizeToId[num]=id++;
                    ans.push_back({i});
                }
                else{
                    ans[sizeToId[num]].push_back(i);
                }
            }
            return ans;
        }
    };

    *map的insert方法不会去除重复元素

  • 相关阅读:
    Spring缓存注解@Cacheable、@CacheEvict、@CachePut使用
    分布式架构2:Nginx下Session存储
    分布式架构3:MySQL集群(Mysql Cluster7.5.5)
    分布式架构1:Nginx实现负载均衡
    Oracle 触发器记录
    [Deprecation Notice] 本博客弃用, 迁移至新博客
    KM算法 O(n^3)最大权完美匹配
    Python 学习笔记(附 Pytorch)
    你一定看的懂的:vlan与交换机端口的三种模式access,trunk和hybrid
    Git代码回滚
  • 原文地址:https://www.cnblogs.com/Dancing-Fairy/p/12793548.html
Copyright © 2020-2023  润新知