leetcode
leetcode 1601 ~ 1650
你能构造出连续值的最大数目

你能构造出连续值的最大数目

难度:

标签:

题目描述

代码结果

运行时间: 95 ms, 内存: 20.2 MB


/*
 * 思路:
 * 1. 使用Java Stream对硬币数组进行排序。
 * 2. 初始化可以构造的连续整数的最大值为0。
 * 3. 遍历排序后的硬币,如果当前硬币值大于可以构造的最大值+1,表示无法构造出下一个连续整数,跳出循环。
 * 4. 否则,累加当前硬币值到可以构造的最大值。
 * 5. 返回可以构造的最大连续整数的数量。
 */

import java.util.Arrays;
import java.util.stream.IntStream;

public class MaxConsecutiveIntegersStream {
    public int getMaxConsecutive(int[] coins) {
        int[] sortedCoins = Arrays.stream(coins).sorted().toArray();
        int maxConsecutive = 0;
        for (int coin : sortedCoins) {
            if (coin > maxConsecutive + 1) {
                break;
            }
            maxConsecutive += coin;
        }
        return maxConsecutive + 1;
    }

    public static void main(String[] args) {
        MaxConsecutiveIntegersStream solution = new MaxConsecutiveIntegersStream();
        int[] coins1 = {1, 3};
        int[] coins2 = {1, 1, 1, 4};
        int[] coins3 = {1, 4, 10, 3, 1};
        System.out.println(solution.getMaxConsecutive(coins1)); // 2
        System.out.println(solution.getMaxConsecutive(coins2)); // 8
        System.out.println(solution.getMaxConsecutive(coins3)); // 20
    }
}

解释

方法:

题解采用了排序加贪心的算法。首先,将硬币数组排序,这样可以从最小的硬币开始处理。定义变量 `ans` 来记录我们可以连续构造的最大值 +1。遍历排序后的硬币数组,对于每个硬币值 `c`,如果 `c` 小于等于 `ans`(这意味着当前硬币可以用来扩展可构造的连续整数范围),则将其加到 `ans` 中。如果遇到一个硬币值大于 `ans`,则无法用该硬币继续扩展连续范围,循环中断。最后返回 `ans`,这就是从0开始,可以构造出的最大连续整数数量。

时间复杂度:

O(n log n)

空间复杂度:

O(log n)

代码细节讲解

🦆
为什么在算法中首先对硬币数组进行排序?这一步骤是如何帮助解决问题的?
在算法中对硬币数组进行排序是为了确保我们能从最小的硬币开始构造连续的整数。这样做可以保证每次添加的硬币都是能够用最小代价扩展当前已构造的连续整数范围的。如果不按顺序来,可能会错过使用较小硬币在某个阶段扩展连续范围的机会。
🦆
在题解中提到,如果硬币值c大于当前的ans值就中断循环。这种情况下是否可能漏掉某些可以构造的连续整数?
按照题解的逻辑,如果硬币值c大于当前的ans值,那么意味着在当前的硬币和之前的硬币组合下无法构造出ans这个值,因此这个值及以上的更大值也无法被构造,所以不会漏掉可以构造的连续整数。因此,中断循环是正确的,因为在这一点之后,无法再扩展连续整数范围。
🦆
解释中提到,变量ans初始化为1是因为可以从0开始构造。那么为什么不是初始化为0而是1?
在这个问题中,变量ans表示的是从0开始,可以构造出的连续整数的最大数量加1。因为我们从0开始构造,所以可以直接构造的整数是0,而不需要任何硬币。初始化ans为1意味着我们可以无障碍地开始计数,从0(无需硬币)到ans-1(需要硬币)的整数范围。
🦆
如果硬币数组全部由相同的元素组成,例如coins = [2,2,2,2],按照题解的算法流程,结果是正确的吗?如果不是,应该如何修改算法来处理这种特殊情况?
按照题解的算法流程,如果硬币数组全部由相同的元素组成,例如coins = [2,2,2,2],算法将无法正确构造连续整数,因为第一个硬币值2已经大于初始化的ans值1。在这种情况下,算法将直接中断循环,返回1,表示只能构造出整数0。为了处理这种情况,算法需要检查如果第一个硬币值大于1是否有其他方式来填补中间缺失的整数,例如使用其他硬币的组合。然而,在此特例中,所有硬币值相同,无法构造1。因此,对于这种特殊情况,算法无需改变,因为只能构造出整数0。

相关问题