leetcode—贪心

不知道各位有没有这种感觉,贪心并不像其他算法那样有多么统一的模式规范,贪心就只有一个核心思想——贪当下。所以怎么去构成代码这件事上并没有其他算法那么机械,比如DP就是转移方程,DFS就是回溯剪枝。就感觉还是挺随意的。(仅代表个人理解,不要骂我呜呜呜)

简单

最长回文串

class Solution {
public:
    void count(char key, unordered_map<char,int>& hash){
        if(hash.find(key) != hash.end()) hash[key]++;
        else hash.emplace(key,1);
    }
    int longestPalindrome(string s) {
        unordered_map<char,int> hash;
        int sum = 0;
        for(char i:s){
            count(i,hash);
        }
        for(auto it = hash.begin();it!=hash.end();){
            if(it->second>1){
                if(it->second%2){
                    sum = sum+it->second-1;
                    it->second = 1;
                    it++;
                }
                else{
                    sum+=it->second;
                    hash.erase(it++);
                }
            }
            else it++;
        }
        if(hash.empty()) return sum;
        return sum+1;
    }
};

成绩:100 83.03
思路:
就感觉很机械啊,不知道为什么会这么快,等会儿去看看思路。
首先我们不要去想怎么去安排这样的一个回文串,而是想想一个回文串有什么特点。
那么很显然一个字符串是左右对称的:
当字符串字符数是偶数个时,字符串就根据中心线左右对称,意味着字符串中的字符都是偶数个,也就是说只要一堆字符每个都是偶数个的,那么就都能拿来构成一个回文串,某些字符多一个少一个就把偶数个拿出来即可。
当字符串字符数是奇数个时,字符串就根据中间字符对称;意味着去掉中心的字符,其余字符就和偶数个(就是上条)规则一样了。
也就是啥呢,一串给定的字符,统计每个字符的数量(我用的hash),只要有字符串是大于1个且为偶数,就可以都拿来构成回文串,然后删除hash表中的对应键值对;如果是奇数,那就拿出最大的偶数个,然后把对应键的值改成1。如果字符个数只有1,跳过即可。
最后统计完出一个sum之后,如果hash是空的,那就构成偶数个字符的回文串。如果hash非空,那就再拿出来一个作为中心字符,构成奇数个字符的回文串。

分发饼干

class Solution {
public:
    int findContentChildren(vector<int>& g, vector<int>& s) {
        sort(g.begin(),g.end());
        sort(s.begin(),s.end());
        int gcur = 0;
        int scur = 0;
        int count = 0;
        while(gcur<g.size() && scur<s.size()){
            if(g[gcur]-s[scur]<=0){  //够了,换下一个小朋友
                gcur++;
                count++;
            }
            scur++;
        }
        return count;
    }
};

成绩:57.20 47.86
思路:
一开始没看见一个小朋友最多只能给一块饼干,还以为给够就算一次,那逻辑就完全不一样了。
首先两个数组排序。贪心嘛,能贪一个是一个。胃口越小的小朋友越容易贪(bushi)
指向当前小朋友,向后遍历饼干,若不能cover,继续遍历,当能cover,计数count+1。指向下一个小朋友 。任何数组遍历到最后就跳出。
就不是很理解,还能有比这快的?最多循环再改一下吧?难道不用sort吗?去看看大佬们的代码。

数组拆分Ⅰ

class Solution {
public:
    int arrayPairSum(vector<int>& nums) {
        sort(nums.begin(),nums.end());
        int sum = 0;
        int cur = 0;
        while(cur<nums.size()){
            sum += nums[cur];
            cur += 2;
        }
        return sum;
    }
};

成绩:93.78 91.76
思路:
想清楚了就很简单
你要想每组取最小求最大的和,怎么样能实现?要让这个最小的尽可能大,那就让每组的插值达到最小,说白了就是排完序,从第一个开始,隔一个取一次,这样就能最大程度避免损失。这个东西应该是有理论的,但是我说不清。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值