题目
343 整数拆分 & 剑指Offer 14- I 剪绳子:
解题
题目 | 解题 |
---|---|
剑指 Offer 14- I. 剪绳子 、343. 整数拆分 | LeetCode343 整数拆分 & 剑指Offer 14- I 剪绳子 |
剑指 Offer 14- II. 剪绳子 II | LeetCode 剑指 Offer 14- II 剪绳子 II |
解题一:动态规划
因为至少要剪成两段,所以先选取第一段的长度 j,再去看剩下的 i - j 不拆分和拆分的情况。
// javascript
var cuttingRope = function(n) {
const dp = new Array(n + 1).fill(0);
for (let i = 2; i <= n; ++i) {
for (let j = 1; j < i; ++j) {
dp[i] = Math.max(dp[i], j * (i - j), j * dp[i - j]);
}
}
return dp[n];
};
官方也给了一版优化的动态规划写法,时间复杂度可以降低到
O
(
n
)
O(n)
O(n),但我没看懂整个推导过程,感性起的可以去看看:优化的动态规划。
解题二:数学
贪心算法 / 数学方法的推导参考:343. 整数拆分(数学推导,清晰图解),高数已经还给老师的可以强行回忆一下子。再不行就记个结论:
b = 2 时,如果拆成
3
∗
(
a
−
1
)
+
3
+
2
,
5
3 * (a - 1) + 3 + 2,5
3∗(a−1)+3+2,5 能剪出的最大乘积是 6,
3
a
−
1
∗
6
=
3
a
∗
2
3^{a - 1} * 6 = 3^{a} * 2
3a−1∗6=3a∗2
// javascript
var cuttingRope = function(n) {
if (n <= 3) return n - 1;
const quotient = Math.floor(n / 3);
const remainder = n % 3;
if (remainder === 0) return Math.pow(3, quotient);
else if (remainder === 1) return Math.pow(3, quotient - 1) * 4;
else return Math.pow(3, quotient) * 2; // remainder = 2;
};