LeetCode 16.11 跳水板 | Java 刷题打卡

331 阅读2分钟

本文正在参加「Java主题月 - Java 刷题打卡」,详情查看 活动链接

题目描述

跳水板

你正在使用一堆木板建造跳水板。有两种类型的木板,其中长度较短的木板长度为shorter,长度较长的木板长度为longer。你必须正好使用k块木板。编写一个方法,生成跳水板所有可能的长度。

返回的长度需要从小到大排列。

示例 1:

输入:
shorter = 1
longer = 2
k = 3
输出: [3,4,5,6]
解释:
可以使用 3 次 shorter,得到结果 3;使用 2 次 shorter 和 1 次 longer,得到结果 4 。以此类推,得到最终结果。

提示

  • 0 < shorter <= longer
  • 0 <= k <= 100000

思路分析

在面对这样一道题的时候,我们很容易想起递归解法,递归解法的时间复杂度是O(2k){O(2^k)},同时还有一种解法是记忆化解法,时间复杂度也是O(2k){O(2^k)},但是看下面的提示,k 的值的最大范围还是挺大的,所以在 leetcode 使用这两种解法时出现超时。所以我们寻求其他解法。

首先考虑边界情况:

如果 k = 0,则不能建造任何跳水板,因此返回空数组。

如果 shorter 和 longer 相等,则建造的跳水板的长度是唯一的,都等于 shorter * k。

然后考虑一般情况,因为是一长一短,因为短木板和长木板是一共使用 k 块,所以一共有 k+1 种情况,每种组合下建造的跳水板长度都是不一样的,一共有 k + 1 中不同的长度,这个很重要,正是因为一长一短,假设 k = 5,一开始 5 个都是 shorter,然后 4 个 shorter,这样 shorter 的个数不断减少,longer 的长度却不断增加,总的长度也是不断递增的。所以一共有 k+1 个不同的长度。同时这样也是升序排列的。

该解法的时间复杂度是O(k){O(k)},空间复杂度也是O(1){O(1)}

代码展示

解法一:时间复杂度是O(k){O(k)},其中 k 是木板数量。短木板和长木板一共使用 k 块,一共有 k+1 种组合,对于每种组合都要计算跳水板的长度。空间复杂度是O(1){O(1)},除了返回值以外,额外使用的空间复杂度为常数。

    //16.11 跳水板 时间复杂度O(n),空间复杂度O(1)
    public static int[] divingBoard(int shorter, int longer, int k) {
        if (k == 0) {
            return new int[]{};
        }
        if (shorter == longer) {
            return new int[]{shorter * k};
        }
        int[] array = new int[k + 1];
        for (int i = 0; i <= k; i++) {
            int a = shorter * (k-i) + longer * i;
            array[i] = a;
        }
        return array;
    }

总结

解答该类题时很容易想到递归解法,但是同时也要考虑到递归的耗时和深度,因为木板是一长一短,所以总的情况是 k + 1。