你正在使用一堆木板建造跳水板。有两种类型的木板,其中长度较短的木板长度为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
我的第一次尝试:
/**
* @param {number} shorter
* @param {number} longer
* @param {number} k
* @return {number[]}
*/
var divingBoard = function (shorter, longer, k) {
let arr = new Array(k).fill(shorter);
let tempArr = new Set();
const len = arr.length || -1;
for (let i = 0; i <= len; i++) {
const sum = arr.reduce((a, b) => a + b);
tempArr.add(sum);
arr[i] = longer;
}
return [...tempArr];
};
结果运行的时候出现了超时,莫名其妙,我用浏览器运行都挺快的。经过我打算执行时间,发现执行 reduce 过程耗时最长,所以我打算优化这一过程。我想到其实就是多少个 shorter 之和或者多少个 longer 之和,于是就得到了下面的代码:
var divingBoard = function (shorter, longer, k) {
let tempArr = new Set();
const len = k || -1;
let m = k,
n = 0;
for (let i = 0; i <= len; i++) {
const sum = m * shorter + n * longer;
tempArr.add(sum);
m-- , n++;
}
return [...tempArr];
};
这样就顺利通过了,但是运行总耗时也花费了 188s ,仍然比较耗时。当前的算法时间复杂度是 O(k) ,空间复杂度也是 O(k)。由于我在乎的是执行速度,那么我重点看怎么提高执行效率。
经过我的努力,成功的将时间减少了 30s :
/**
* @param {number} shorter
* @param {number} longer
* @param {number} k
* @return {number[]}
*/
var divingBoard = function (shorter, longer, k) {
if (k === 0) {
return [];
}
let tempArr = [];
for (let m = k, n = 0; n <= k; m-- , n++) {
const sum = m * shorter + n * longer;
if (tempArr[tempArr.length - 1] !== sum) {
tempArr.push(sum);
}
}
return tempArr;
};
以前慢主要是从 Set 到 Array 也比较耗时,因为相较于上面的算法,这次的算法去重自己做的,当然这取决于数组的值是一个递增的过程,所以即便有重复也是跟前一个元素有关系。现在耗时为: 152s,我感觉还能减少,在我这个算法的基础上。我再思考思考。
来源:力扣(LeetCode)