题目
https://leetcode-cn.com/problems/jian-sheng-zi-lcof/
方法一:动态规划 时间O(n^2) 空间O(n)
java
class Solution {
public int cuttingRope(int n) {
int[] dp = new int[n+1];
for(int i = 2; i <= n; i++){
for(int j = 1; j <= i-1; j++){
dp[i] = Math.max(dp[i],Math.max(j*dp[i-j],j*(i-j)));
}
}
return dp[n];
}
}
js
var cuttingRope = function(n) {
var dp = new Array(n+1).fill(0);
for(var i = 2; i < n+1; i++){
for(var j = 1; j <= i-1; j++){
dp[i] = Math.max(dp[i],Math.max(j*dp[i-j],j*(i-j)));
}
}
return dp[n];
};
方法二:贪心算法,数学推导 时间O(n) ,空间O(1)
https://leetcode-cn.com/problems/jian-sheng-zi-lcof/solution/mian-shi-ti-14-i-jian-sheng-zi-tan-xin-si-xiang-by/
核心思路是:尽可能把绳子分成长度为3的小段,这样乘积最大
1.如果 n == 2,返回1,如果 n == 3,返回2,两个可以合并成n小于4的时候返回n - 1
2.如果 n == 4,返回4
3.如果 n > 4,分成尽可能多的长度为3的小段,每次循环长度n减去3,乘积res乘以3;最后返回时乘以小于等于4的最后一小段(最后一小段如果是1,2,3,正好就是其不需划分乘起来值最大)
4.以上2和3可以合并
java
class Solution {
public int cuttingRope(int n) {
if(n < 4){
return n - 1;
}
int res = 1;
while(n > 4){
res *= 3;
n -= 3;
}
return res * n;
}
}
/**
* @param {number} n
* @return {number}
*/
var cuttingRope = function(n) {
if(n < 4){
return n-1;
}
var res = 1;
while(n >4){
res *= 3;
n -= 3;
}
return res * n;
};
ii题目 n的范围改变(2,1000),此时动态规划可能会运行超时。
贪心
步骤如下:
如果 n == 2,返回1,如果 n == 3,返回2,两个可以合并成n小于4的时候返回n - 1
如果 n == 4,返回4
如果 n > 4,分成尽可能多的长度为3的小段,每次循环长度n减去3,乘积res乘以3;最后返回时乘以小于等于4的最后一小段;每次乘法操作后记得取余就行
以上2和3可以合并
JS
/**
* @param {number} n
* @return {number}
*/
var cuttingRope = function(n) {
if(n < 4) return n-1;
var res = 1;
while(n > 4){
res = res*3%1000000007;
n -= 3;
}
return res*n%1000000007;
};