题目来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/diving-board-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
你正在使用一堆木板建造跳水板。有两种类型的木板,其中长度较短的木板长度为shorter,长度较长的木板长度为longer。你必须正好使用k块木板。编写一个方法,生成跳水板所有可能的长度。
返回的长度需要从小到大排列。
示例:
输入:
shorter = 1
longer = 2
k = 3
输出: {3,4,5,6}
提示:
- 0 < shorter <= longer
- 0 <= k <= 100000
题目意思很好理解,就是用总数k的跳水板去看有多少种长度的可能。
- 可能会有人首先想到递归,递归能解决这个问题,从第一个开始,每次递归都考虑用长跳水板和短跳水板,直到递归次数为k时,结束递归,并把最后的长度添加进返回的数组中。但是递归这种方法损耗的时间和空间都非常大(相对来说),所以有可能会存在栈溢出、超时等情况,不建议使用。
- 第二种方法就是找规律。对于shorter = 1,longer = 2,k = 3这个测试用例来说。所有的可能性如下
shorter | longer |
---|---|
0 | 3 |
1 | 2 |
2 | 1 |
3 | 0 |
只要我们多测试几个用例,就可以发现结果个数为 k+1,而最小的结果就是全部都为 短跳水板 的时候,后面每一个都为前面的结果加上长跳水板与短跳水板的长度差,即构成了等差数列,也就是说(假设返回结果数组为 rs[])
- rs [ 0 ] = k * shorter
- rs [ n ] = rs [ n - 1 ] + longer - shorter
然后再考虑特殊情况,当跳水板总数k=0时,应返回空数组
当长跳水板与短跳水板长度相同时,直接返回
new int[] {shorter * k} 即可
根据上述描述情况,可以写出以下代码:
class Solution {
public int[] divingBoard(int shorter, int longer, int k) {
//特殊情况一 跳板数为0
if (k == 0) {
return new int[0];
}
//特殊情况二 长跳板与短跳板长度一样
if (shorter == longer) {
return new int[]{
shorter * k};
}
int[] rs = new int[k + 1];
rs[0] = shorter * k;
for (int i = 1; i <= k; i++) {
rs[i] = rs[i - 1] + (longer - shorter);
}
return rs;
}
}
提交截图: