leetcode
leetcode 2851 ~ 2900
小张刷题计划

小张刷题计划

难度:

标签:

题目描述

English description is not available for the problem. Please switch to Chinese.

代码结果

运行时间: 214 ms, 内存: 26.5 MB


/*
 * 题目思路:
 * 1. 使用stream来计算左右边界。
 * 2. 其他部分与普通Java解法类似,只是运用了stream。
 */
import java.util.Arrays;

public class LeetCodeSolutionStream {
    public int minTime(int[] time, int m) {
        int left = Arrays.stream(time).max().getAsInt();
        int right = Arrays.stream(time).sum();
        while (left < right) {
            int mid = (left + right) / 2;
            if (canFinish(time, m, mid)) {
                right = mid;
            } else {
                left = mid + 1;
            }
        }
        return left;
    }

    private boolean canFinish(int[] time, int m, int maxTime) {
        int days = 1, totalTime = 0;
        for (int t : time) {
            if (totalTime + t > maxTime) {
                days++;
                totalTime = t;
                if (days > m) return false;
            } else {
                totalTime += t;
            }
        }
        return true;
    }
}

解释

方法:

题解采用了二分查找结合贪心算法的策略。首先定义f函数,该函数用于判断在最大单日时间T的限制下,小张完成所有题目需要的天数。对于每道题,我们维护当前天的总时间s和当天最耗时的题目时间max_time。如果添加新题会使总时间s超过T,那么新开一天,并将当前题作为新一天的第一题。在minTime函数中,通过调整T的值(二分查找)来找到使得f函数返回的天数不超过m的最小T值。

时间复杂度:

O(n log(sum(time)))

空间复杂度:

O(1)

代码细节讲解

🦆
在二分查找的过程中,为什么`low`的初始值设为0,而不是考虑题目中可能存在的最小耗时?
在这个题解中,`low` 设为 0 实际上可能不是最优的选择,因为一个更合理的起始值应该是题目中的最小耗时。这样设定是因为,我们在考虑任何合法的单日时间 `T` 时,至少应保证 `T` 不小于任何单个题目的耗时,以确保每个题目都可以在某一天被完成。如果 `low` 设置为 0,则在函数 `f` 中会有额外的判断和处理,确保不会出现无法分配题目的情况。因此,从理论和实用角度看,将 `low` 设置为 `time` 中的最小值是更合适的,这可以减少二分查找的范围并提高效率。
🦆
题解中提到使用`max_time`来记录最耗时的题目,这种策略在哪些情况下可能会导致不必要的天数增加?
使用 `max_time` 来记录最耗时的题目的策略可能在题目的时间分布不均时导致不必要的天数增加。例如,如果一天中开始就遇到一个极端耗时的题目,后续题目耗时都很短,这种策略会导致该天只能完成很少的题目,而实际上将一些短的题目安排在耗时题目的同一天可能是可行的。这样就可能增加总天数,尤其是当耗时最长的题目和其他题目的耗时差异很大时更为明显。
🦆
在确定二分搜索的上界时,为什么选择`sum(time)`作为上界,这是否意味着在某些情况下一个人一天内可能尝试完成所有题目?
选择 `sum(time)` 作为上界是因为这是在极端情况下,即不将任何题目分到不同天,一个人在一天内尝试完成所有题目的总耗时。虽然从实际情况来看,这通常不是一个有效的策略,因为这样会导致需要的天数为1,这通常不可能满足题目的其他限制(如天数限制 `m`)。然而,将上界设置为 `sum(time)` 确保了二分搜索能覆盖所有可能的 `T` 值,从最小可能的 `T`(题目耗时的最小值)到最大可能的 `T`(所有题目耗时之和)。

相关问题