跳转至

面试题 16.11. 跳水板

题目描述

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

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

示例:

输入:
shorter = 1
longer = 2
k = 3
输出: {3,4,5,6}

提示:

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

解法

方法一:分类讨论

如果 $k=0$,则不存在任何一种方案,我们可以直接返回空列表。

如果 $shorter=longer$,则我们只能使用长度为 $longer \times k$ 的木板,因此我们直接返回长度为 $longer \times k$ 的列表。

否则,我们可以使用长度为 $shorter \times (k-i) + longer \times i$ 的木板,其中 $0 \leq i \leq k$。我们在 $[0, k]$ 的范围内枚举 $i$,并计算对应的长度即可。对于不同的 $i$,我们不会得到相同的长度,这是因为,假如有 $0 \leq i \lt j \leq k$,那么两者长度差为 $shorter \times (k-i) + longer \times i - shorter \times (k-j) - longer \times j$,整理得到长度差 $(i - j) \times (longer - shorter) \lt 0$。因此,对于不同的 $i$,我们会得到不同的长度。

时间复杂度 $O(k)$,其中 $k$ 为木板数量。忽略答案的空间消耗,空间复杂度 $O(1)$。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
class Solution:
    def divingBoard(self, shorter: int, longer: int, k: int) -> List[int]:
        if k == 0:
            return []
        if longer == shorter:
            return [longer * k]
        ans = []
        for i in range(k + 1):
            ans.append(longer * i + shorter * (k - i))
        return ans
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class Solution {
    public int[] divingBoard(int shorter, int longer, int k) {
        if (k == 0) {
            return new int[0];
        }
        if (longer == shorter) {
            return new int[] {longer * k};
        }
        int[] ans = new int[k + 1];
        for (int i = 0; i < k + 1; ++i) {
            ans[i] = longer * i + shorter * (k - i);
        }
        return ans;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
class Solution {
public:
    vector<int> divingBoard(int shorter, int longer, int k) {
        if (k == 0) return {};
        if (longer == shorter) return {longer * k};
        vector<int> ans;
        for (int i = 0; i < k + 1; ++i)
            ans.push_back(longer * i + shorter * (k - i));
        return ans;
    }
};
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
func divingBoard(shorter int, longer int, k int) []int {
    if k == 0 {
        return []int{}
    }
    if longer == shorter {
        return []int{longer * k}
    }
    var ans []int
    for i := 0; i < k+1; i++ {
        ans = append(ans, longer*i+shorter*(k-i))
    }
    return ans
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
function divingBoard(shorter: number, longer: number, k: number): number[] {
    if (k === 0) {
        return [];
    }
    if (longer === shorter) {
        return [longer * k];
    }
    const ans: number[] = [k + 1];
    for (let i = 0; i <= k; ++i) {
        ans[i] = longer * i + shorter * (k - i);
    }
    return ans;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class Solution {
    func divingBoard(_ shorter: Int, _ longer: Int, _ k: Int) -> [Int] {
        if k == 0 {
            return []
        }
        if shorter == longer {
            return [shorter * k]
        }

        var ans = [Int](repeating: 0, count: k + 1)
        for i in 0...k {
            ans[i] = longer * i + shorter * (k - i)
        }
        return ans
    }
}

评论