1482-制作 m 束花所需的最少天数

题目

1482. 制作 m 束花所需的最少天数 - 力扣(LeetCode) (leetcode-cn.com)

思路

首先我们需要检查总的花朵数量是否足够制作花束,如果不够则直接返回-1

在花朵够的情况下,最大的等待天数max_day是所有花的开放的天数(max(bloomDay)),最少等待的天数min_day是第一朵花开放的天数(min(bloomDay))。然后我们需要确定在第d天时( d ∈ [ m i n _ d a y , m a x d a y ] d \in [min\_day, max_day] d[min_day,maxday]),开放的花是否足够制作所需的花束,判断过程较为简单,我们使用一个变量f记录连续开放的花数量,顺序扫描bloomDay,当bloomDay[i] <= d时表示该花已经开放,我们将连续开放的花数量f加1,否则,则设置f0(当前连续的花朵不够制作一个花束)。当f == k时表示已经有足够的花制作一个花束,我们将m减去1 ,并重新设置f为0以搜索下一个足够制作花束的连续花朵。最终如果m > 0表示无法制作足够的花束,否则表示可以制作足够的花束。

我们可以从min_day开始逐个测试,直到刚好能够满足制作所有花束的天数即为最少天数,不过更快的方式是使用二分搜索来确定最少天数。对于正确答案所处的范围[min_day, max_day],如果其中的一个值d不满足需求,那么正确答案必然>d,因此正确答案的范围是 [d+1, max_day],如果d满足需求,那么可能更小的d也满足需求,即正确答案<=d,因此正确答案的范围是[min_day, d]。直到正确答案只包含一个值时,就是最终的答案。

代码

class Solution {
public:
    int minDays(vector<int>& bloomDay, int m, int k) {

        if(bloomDay.size() < (m * k)) {
            return -1;
        }

        int min_day = INT_MAX;
        int max_day = INT_MIN;
        for(int n:bloomDay) {
            if (n > max_day) {
                max_day = n;
            }
            if (n < min_day) {
                min_day = n;
            }
        }

        int day = (min_day + max_day) / 2;
        while(min_day != max_day) {
            if (check(bloomDay, m, k, day) == false) {
                min_day = day + 1;
            } else {
                max_day = day;
            }
            day = (min_day + max_day) / 2;
        }
        return day;
    }

    bool check(vector<int>& bloomDay, int m, int k, int day) {
        int flower = 0;

        for(int n: bloomDay) {
            if (n <= day) {
                flower++;
            } else {
                flower=0;
            }
            if (flower == k) {
                m--;
                if (m == 0) {
                    break;
                }
                flower = 0;
            }
        }
        return (m > 0)? false : true;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值