leetcode-1705:吃苹果的最大数目

简介: leetcode-1705:吃苹果的最大数目

题目

题目链接

有一棵特殊的苹果树,一连 n 天,每天都可以长出若干个苹果。在第 i 天,树上会长出 apples[i] 个苹果,这些苹果将会在 days[i] 天后(也就是说,第 i + days[i] 天时)腐烂,变得无法食用。也可能有那么几天,树上不会长出新的苹果,此时用 apples[i] == 0 且 days[i] == 0 表示。

你打算每天 最多 吃一个苹果来保证营养均衡。注意,你可以在这 n 天之后继续吃苹果。

给你两个长度为 n 的整数数组 days 和 apples ,返回你可以吃掉的苹果的最大数目。

示例 1:

输入:apples = [1,2,3,5,2], days = [3,2,1,4,2]
输出:7
解释:你可以吃掉 7 个苹果:
- 第一天,你吃掉第一天长出来的苹果。
- 第二天,你吃掉一个第二天长出来的苹果。
- 第三天,你吃掉一个第二天长出来的苹果。过了这一天,第三天长出来的苹果就已经腐烂了。
- 第四天到第七天,你吃的都是第四天长出来的苹果。

示例 2:

输入:apples = [3,0,0,0,0,2], days = [3,0,0,0,0,2]
输出:5
解释:你可以吃掉 5 个苹果:
- 第一天到第三天,你吃的都是第一天长出来的苹果。
- 第四天和第五天不吃苹果。
- 第六天和第七天,你吃的都是第六天长出来的苹果。

解题

方法一:贪心+优先队列

参考链接

用优先队列存储,vector{苹果到期日子,苹果个数}

先摘当天的苹果

然后把过期的苹果扔掉

每次吃最先要过期的苹果。(先pop出来,苹果个数减1,如果个数大于0或者第二天还能吃,就push回来)

class Solution {
public:
    int eatenApples(vector<int>& apples, vector<int>& days) {
        struct cmp{
            bool operator()(vector<int>&a,vector<int>&b){
                return a[0]>b[0];
            }
        };
        priority_queue<vector<int>,vector<vector<int>>,cmp> q;
        int n=apples.size();
        int time=0,res=0;//time记录日期,res记录吃的苹果数
        while(time<n||!q.empty()){
            if(time<n&&apples[time]>0) q.push({time+days[time]-1,apples[time]});
            while(!q.empty()&&time>q.top()[0]) q.pop();//将过期苹果扔掉
            if(!q.empty()){//如果还有苹果,就吃掉,将它pop出来,吃掉一个,如果数量还>0的就push回去
                vector<int> cur=q.top();
                q.pop();
                if(--cur[1]>0&&cur[0]>time) q.push(cur);//数量大于0且第二天还能吃,就push回去
                res++;
            }
            time++;
        }
        return res;
    }
};

可以发现把vector换成pair后具有更快的速度

class Solution {
public:
    int eatenApples(vector<int>& apples, vector<int>& days) {
        struct cmp{
            bool operator()(pair<int,int>&a,pair<int,int>&b){
                return a.first>b.first;
            }
        };
        priority_queue<pair<int,int>,vector<pair<int,int>>,cmp> q;
        int n=apples.size();
        int time=0,res=0;//time记录日期,res记录吃的苹果数
        while(time<n||!q.empty()){
            if(time<n&&apples[time]>0) q.push({time+days[time]-1,apples[time]});
            while(!q.empty()&&time>q.top().first) q.pop();//将过期苹果扔掉
            if(!q.empty()){//如果还有苹果,就吃掉,将它pop出来,吃掉一个,如果数量还>0的就push回去
                pair<int,int> cur=q.top();
                q.pop();
                if(--cur.second>0&&cur.first>time) q.push(cur);//数量大于0且第二天还能吃,就push回去
                res++;
            }
            time++;
        }
        return res;
    }
};

前面是pair 后面是vector

方法二:贪心+MapTree

map的底层通过红黑树实现,是一颗平衡的二叉搜索树,因此键是有序的(从小到大),因此可以使用map代替优先队列进行自动排序。

public:
    int eatenApples(vector<int>& apples, vector<int>& days) {
        int res=0;
        int time=0;
        int n=apples.size();
        map<int,int> map;
        while(time<n||!map.empty()){
            if(time<n&&apples[time]>0) map[time+days[time]-1]+=apples[time];
            while(!map.empty()&&time>map.begin()->first) map.erase(map.begin()->first);
            if(!map.empty()){
                if(--map.begin()->second==0) map.erase(map.begin()->first);
                res++;
            }
            time++;
        }
        return res;
    }
};


相关文章
|
4月前
|
算法 测试技术 C#
区间合并|LeetCode2963:统计好分割方案的数目
区间合并|LeetCode2963:统计好分割方案的数目
|
4月前
|
算法 测试技术 C#
【贪心算法】LeetCode2071:你可以安排的最多任务数目
【贪心算法】LeetCode2071:你可以安排的最多任务数目
|
4月前
|
算法 安全 测试技术
[组合数学]LeetCode:2954:统计感冒序列的数目
[组合数学]LeetCode:2954:统计感冒序列的数目
|
4月前
leetcode-1601:最多可达成的换楼请求数目
leetcode-1601:最多可达成的换楼请求数目
40 0
|
2月前
|
存储 算法
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
|
2月前
2670.找出不同元素数目差数组-力扣(LeetCode)
2670.找出不同元素数目差数组-力扣(LeetCode)
21 0
|
4月前
|
算法
"刷题记录:哈希表+双指针 | leetcode-2465. 不同的平均值数目 "
该文段是一篇关于编程题目的解答,主要讨论如何找到数组中所有不同平均值的个数。作者首先使用排序和哈希集来解决,将数组转为列表排序后,通过双指针计算平均值并存入哈希集以去重。然后,作者发现可以优化方案,通过双指针在排序后的数组中直接计算两数之和,用哈希集记录不重复的和,从而避免实际计算平均值,提高了算法效率。最终代码展示了这两种方法。
43 0
|
4月前
[leetcode~数位动态规划] 2719. 统计整数数目 hard
[leetcode~数位动态规划] 2719. 统计整数数目 hard
|
4月前
|
算法 测试技术 C#
【图论】【分类讨论】LeetCode3017按距离统计房屋对数目
【图论】【分类讨论】LeetCode3017按距离统计房屋对数目
|
4月前
|
存储
leetcode2744. 最大字符串配对数目
leetcode2744. 最大字符串配对数目
30 0