Leetcode刷题——贪心算法题目汇总

265 阅读2分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第27天,点击查看活动详情

贪心

1405. 最长快乐字符串

题目 如果字符串中不含有任何 'aaa','bbb' 或 'ccc' 这样的字符串作为子串,那么该字符串就是一个「快乐字符串」。

给你三个整数 a,b ,c,请你返回 任意一个 满足下列全部条件的字符串 s:

s 是一个尽可能长的快乐字符串。 s 中 最多 有a 个字母 'a'、b 个字母 'b'、c 个字母 'c' 。 s 中只含有 'a'、'b' 、'c' 三种字母。 如果不存在这样的字符串 s ,请返回一个空字符串 ""。

示例 1:

输入:a = 1, b = 1, c = 7 输出:"ccaccbcc" 解释:"ccbccacc" 也是一种正确答案。

示例 2:

输入:a = 2, b = 2, c = 1 输出:"aabbc"

示例 3:

输入:a = 7, b = 1, c = 0 输出:"aabaa" 解释:这是该测试用例的唯一正确答案。

提示:

0 <= a, b, c <= 100 a + b + c > 0

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/lo… 分析 首先从题目中我们可以看出,长度越长的串越容易造成重复字符,所以我们要尽可能的使用最长的字符串中的字符。这样问题就变成了判断选出来的字符与当前目标串的最后两个字符的关系,如果加上这个字符就已经够三个连续字符了,就选下一个次长串的字符。当完全选不出任何字符的时候终止循环即可 代码

struct Node{
    char ch;
    int num;
};
class Solution {
public:
    string longestDiverseString(int a, int b, int c) {
        string ans;
        vector<Node> v;
        Node na, nb, nc;
        na.ch = 'a', na.num = a;
        v.push_back(na);
        nb.ch = 'b', nb.num = b;
        v.push_back(nb);
        nc.ch = 'c', nc.num = c;
        v.push_back(nc);

        int cnt=0;
        while(1){
            sort(v.begin(), v.end(), [](Node a, Node b){
                return a.num > b.num;
            });
            bool flag = false;
            for(int i=0; i < v.size(); i++){
                if(v[i].num > 0 && (ans.size()==0 || ans.size()==1|| ans[ans.size()-1] != v[i].ch || ans[ans.size()-2] != v[i].ch)){
                    v[i].num --;
                    ans += v[i].ch;
                    if(v[i].num == 0){
                        cnt++;
                    }
                    flag = true;
                    break;
                }
            }
            if(!flag){
                break;
            }
        }
    
        return ans;
    }
};

1414. 和为 K 的最少斐波那契数字数目

题目 给你数字 k ,请你返回和为 k 的斐波那契数字的最少数目,其中,每个斐波那契数字都可以被使用多次。

斐波那契数字定义为:

F1 = 1 F2 = 1 Fn = Fn-1 + Fn-2 , 其中 n > 2 。 数据保证对于给定的 k ,一定能找到可行解。

示例 1:

输入:k = 7 输出:2 解释:斐波那契数字为:1,1,2,3,5,8,13,…… 对于 k = 7 ,我们可以得到 2 + 5 = 7 。

示例 2:

输入:k = 10 输出:2 解释:对于 k = 10 ,我们可以得到 2 + 8 = 10 。

示例 3:

输入:k = 19 输出:3 解释:对于 k = 19 ,我们可以得到 1 + 5 + 13 = 19 。

提示:

1 <= k <= 10^9

来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/fi… 分析 由斐波那契数列的性质可知,后面的数一定可以由前面的几个数的和组成,所以要让取的数字数量最小就要尽可能的取大的数,让k减去取得的最大的数就将问题转换成了子问题 代码

class Solution {
public:
    int findMinFibonacciNumbers(int k) {
        int cnt=0;
        vector<int> v;
        int a=1, b=1, p=1;
        v.push_back(1);
        v.push_back(1);
        while(p <= k){
            p = a + b;
            a = b;
            b=p;
            v.push_back(p);
        } 
        for(int i=v.size()-1; i >= 0; i--){
            if(v[i] <= k){
                k-= v[i];
                cnt++;
            }
        }
        return cnt;
    }
};