你正在使用一堆木板建造跳水板。有两种类型的木板,其中长度较短的木板长度为shorter,长度较长的木板长度为longer。你必须正好使用k块木板。编写一个方法,生成跳水板所有可能的长度。返回的长度需要从小到大排列。
示例:
输入: shorter = 1 longer = 2 k = 3 输出: {3,4,5,6}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/diving-board-lcci
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
分析
虽然在力扣上这题的标签是递归,但是仔细分析会发现并不需要递归。先不考虑特殊情况,做如下分析:
- 可知对于任意一组参数(shorter、longer、k),最小的组合是k个shorter,相应地,最大的组合即为longer;
- 由题知,有k块木板,考虑任意选择一种木板(比如shorter),选择的情况可能为0、1、2…k共
k + 1
可能,因此最终的结果也是k + 1
种; - 通过第二点可知,共有
k + 1
种可能,因此可以假设第一种是全选shorter,长度设为len,第二种选择是将第一种选择中的一个shorter替换为longer,那么长度即为len + (longer - shorter)
,以此类推,即每次增加一个step(longer - shorter),最终加到longer * k
即可得到最大值。
再考虑特殊情况:
- 当k不为正数时,无意义,按照题目给的返回值,返回[]即可;
- 当shorter和longer一样大的时候,可以无论k取何值,只有一个结果(shorter * k 或者说 longer * k)。
代码
public int[] divingBoard(int shorter, int longer, int k) {
if (k <= 0) {
return new int[0];
}
if (shorter == longer) {
return new int[]{shorter * k};
}
int n = k + 1;
int[] res = new int[n];
int step = longer - shorter;
for (int i = 0, val = shorter * k; i < n; i++, val += step) {
res[i] = val;
}
return res;
}
复杂度分析
- 时间复杂度:只有一重循环遍历,循环体内为常数操作,故为O(n);
- 空间复杂度:只有在存储结果使用了额外的
k + 1
个空间,故为O(n)。