【二分】B016_LC_製作 m 束花所需的最少天數(枚舉時檢查)

一、Problem

Given an integer array bloomDay, an integer m and an integer k.

We need to make m bouquets. To make a bouquet, you need to use k adjacent flowers from the garden.

The garden consists of n flowers, the ith flower will bloom in the bloomDay[i] and then can be used in exactly one bouquet.

Return the minimum number of days you need to wait to be able to make m bouquets from the garden. If it is impossible to make m bouquets return -1.

Input: bloomDay = [1,10,3,10,2], m = 3, k = 1
Output: 3
Explanation: Let's see what happened in the first three days. x means flower bloomed and _ means flower didn't bloom in the garden.
We need 3 bouquets each should contain 1 flower.
After day 1: [x, _, _, _, _]   // we can only make one bouquet.
After day 2: [x, _, _, _, x]   // we can only make two bouquets.
After day 3: [x, _, x, _, x]   // we can make 3 bouquets. The answer is 3.

二、Solution

方法一:二分

這一題鬼上身了,好不容易想到二分,誰知道在線性檢查的時候因爲想那個相鄰想得太複雜了,浪費好多時間去改呀…

class Solution {
    boolean ck(int d, int[] bd, int m, int k) {
        int cnt = 0;
        for (int i = 1; i < bd.length; i++) {
            if (bd[i] <= d && bd[i-1] <= d) 
                cnt++;
            if (cnt >= k)
                m--; 
        }
        return m == 0;
    }
    public int minDays(int[] bd, int m, int k) {
        int n = bd.length, l = 0, r = (int) 1e9+5;

        while (l < r && m > 0) {
            int mid = l + r >>> 1;
            if (ck(mid, bd, m, k)) {
                r = m-1;
                m--;
            } else {
                l = mid + 1;
            }
        }
        return r;
    }
}

爲什麼要這樣想呢?直接一個一個得枚舉,然後如果遇到一個花的 bloom[i] > d 直接將計數器清零即可;還有不要等到最後才檢查 m == 0 是否成立,應該在循環的時候就去檢查了。

class Solution {
    boolean ck(int d, int[] bd, int m, int k) {
        int cnt = 0, n = bd.length;
        for (int i = 0; i < n; i++) {
            if (bd[i] <= d) cnt++;
            else            cnt = 0;
            if (cnt == k) {
                m--; 
                cnt = 0;
            }
            if (m == 0)
                return true;
        }
        return false;
    }
    public int minDays(int[] bd, int m, int k) {
        int n = bd.length, l = 0, r = (int) 1e9;
        if (m * k > n)
            return -1;
        
        while (l < r) {
            int mid = l + r >>> 1;
            if (ck(mid, bd, m, k))  r = mid;
            else                    l = mid + 1;
        }
        return r;
    }
}

複雜度分析

  • 時間複雜度:O(nlogn)O(nlogn)
  • 空間複雜度:O(1)O(1)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章