LeetCode | 面试题16.11.跳水板

你正在使用一堆木板建造跳水板。有两种类型的木板,其中长度较短的木板长度为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)。

猜你喜欢

转载自blog.csdn.net/qq_41698074/article/details/107215585