0
点赞
收藏
分享

微信扫一扫

算法训练:贪心

蛇发女妖 2022-05-04 阅读 93
leetcodec++

文章目录

1.1221. 分割平衡字符串

原题链接

          经典的括号匹配类型的问题,甚至比经典的括号匹配更简单。一个字符串是平衡字符串,那么在字符串中L的数量要等于R,扫描一边数组并记录即可。

class Solution {
public:
    int balancedStringSplit(string s) {
        int ans=0;
        int cntr=0,cntl=0;
        for(int i=0;i<s.size();i++){
            s[i]=='R'?cntr++:cntl++;
            if(cntr==cntl){
                cntr=cntl=0;
                ans++;
            }
        }
        return ans;
    }
};

2.1827. 最少操作使数组递增

原题链接

         按照题目模拟即可,遍历一遍数组如果当前数字比之前的小或相等就把他变成前一个数字加1,否则更新前一个数字。

class Solution {
public:
    int minOperations(vector<int>& nums) {
        if(nums.size()==0){
            return 0;
        }
        int ans=0;
        int prev=nums[0];
        for(int i=1;i<nums.size();++i){
            if(prev>=nums[i]){
                ans+=prev-nums[i]+1;
                prev++;
            }else prev=nums[i];
        }
        return ans;
    }
};

3.2144. 打折购买糖果的最小开销

原题链接

         首先我们为了充分利用条件,也就是想要使得免费获得的糖果价格最高,那么我们就要依次选择糖果价格最高的两个,并免费获得剩下的价格最高的糖果。至于为什么不依次买价格最小的两个或者是价格最大和最小的两个是因为如果是这样那么就无法免费获得任何一个糖果了得不偿失。

class Solution {
public:
    int minimumCost(vector<int>& cost) {
        sort(cost.begin(),cost.end(),[&](const int& a,const int &b){
            return a>b;
        });
        int ans=0;
        for(int i=0;i<cost.size();++i){
            ans+=cost[i];
            if(i<cost.size()-1){
                ans+=cost[i+1];
                i+=2;
            }
        }
        return ans;
    }
};

4.1400. 构造 K 个回文字符串

原题链接

         其实这道题看起来十分复杂,又是回文又是要在整个字符串里面构造出来k个回文串,单单是一个回文可能我们以前在做的时候就很烦了。
         现在我们分析原字符串s,先把其中的每个字符出现的频率映射到一个数组hash中去。现在将其出现次数分为奇数次和偶数次,对于偶数次的字母我们不用管,因为他们之间组合总能构成一个回文串。而对于奇数组的字母,有他们参与构造的回文串就有一下两种形式 :
         1.该字母单独构成一个回文串,比如“aaa”,“aa",“aaaaa”
         2.将该字母插入到某个由任意个偶数构成的一个回文串中比如"bbcbb",“aabbcccbba    a”,“cceeeeeefeeeeeecc”.
         现在我们开始思考构造的回文串个数和偶数字符以及奇数字符的个数之间的关系。从上面的例子可以看出,偶数字符在构造回文串的过程中起到的往往是辅助作用,因为一个回文串可以仅仅只有偶数字符组成也可以有由若干个偶数字符组成,更可以由若干个偶数字符和一个奇数字符组成。所以某个偶数字符可以任意添加到某个已经构成的回文串中,不影响最终个数。所以这里仅仅考虑奇数字符的个数。
         那么接下来就十分简单了,我们统计字符串中奇数字符的个数,如果有小于等于K个的奇数字符,就一定可以将字符串中所有字符用完构成k个回文串,但是大于了K个就绝对无法将所有字符用完构成k个回文串。另外,如果字符串中没有出现频率是奇数的字符,这个时候该怎么办?这就代表此时字符串中全为偶数个字符,将他们任意拆分,一定可以构成k个回文串,比如s=”aabb",k=3,那么我们的回文串可以为“a",“a”,“bb"或者"b”,“b”,“aa”,这个时候也返回true。

class Solution {
public:
    bool canConstruct(string s, int k) {
        if(k>s.size()){
            return false;
        }
        int hash[26];
        int i;
        int num=0;
        memset(hash,0,sizeof(hash));
        for(i=0;i<s.size();i++){
            ++hash[s[i]-'a'];
        }
        for(i=0;i<26;++i){
            if(((hash[i]%2)&1)){
                num++;
            }
        }
        return num<=k||num==0;
    }
};
举报

相关推荐

0 条评论