class Solution {
public int cuttingRope(int n) {
if(n == 2) return 1;
if(n == 3) return 2;
int res = n / 3;
int mod = n % 3;
if(mod == 0){
return pow(3, res);
}else if(mod == 1){
return pow(3, res - 1) * 4;
}else{
return pow(3, res) * 2;
}
}
public int pow(int a, int b){
int sum = 1;
int t = a;
while(b != 0){
if((b & 1) == 1){
sum *= t;
}
b = b >> 1;
t *= t;
}
return sum;
}
}
def cuttingRope(n):
# 2、3为特殊情况
if n == 2:
return 1
if n == 3:
return 2
res = n // 3
mod = n % 3
if mod == 0:
return pow(3,res)
if mod == 1:
# 如果余数是1,将1和一个3凑成一个4
return pow(3,res-1) * 4
if mod == 2:
return pow(3,res) * 2
class Solution {
public int cuttingRope(int n) {
int[] f = new int[n+1];
f[2] = 1;
for (int i = 2; i <= n; i++) {
for (int j = 1; j < i; j++) {
f[i] = Math.max(
f[i], Math.max(j * (i-j), f[j] * (i-j))
);
}
}
return f[n];
}
}
数学也不咋会
class Solution {
public int cuttingRope(int n) {
if (n <= 3) return n-1;
int a = n / 3, b = n % 3;
if (b == 0) return (int) Math.pow(3, a);
if (b == 1) return (int) Math.pow(3, a - 1) * 4;
return (int) Math.pow(3, a) * 2;
}
}
class Solution:
def cuttingRope(self, n: int) -> int:
# 推理判断:当绳子长度大于3时,需要尽量把绳子切分成差不多一样的长度,且不能同时存在2和4的长度,2+4=3+3
# 特殊情况
if n == 2:
return 1
if n == 3:
return 2
# 绳子长度除3取整表示可以切分成这么多段的3,余数为1时可以合并一个3,余数为2时保持不变
res = n // 3
mod = n % 3
if mod == 0:
return 3 ** res
elif mod == 1:
return 3 ** (res - 1) * 4
else:
return 3 ** res * 2
class Solution {
public int cuttingRope(int n) {
if(n <= 3) return n - 1;
int a = n / 3, b = n % 3;
if(b == 0) return (int)Math.pow(3, a);
if(b == 1) return (int)Math.pow(3, a - 1) * 4;
return (int)Math.pow(3, a) * 2;
}
}
class Solution {
public int cuttingRope(int n) {
if(n <= 2) return 1;
if(n == 3) return 2;
int res = n / 3;
int k = n % 3;
if(k == 0){
return (int)Math.pow(3,res);
}else if(k == 1){
return (int)Math.pow(3,res - 1)*4;
}else{
return (int)Math.pow(3,res)*k;
}
}
}
//快速幂方式
class Solution {
public int cuttingRope(int n) {
if(n <= 2) return 1;
if(n == 3) return 2;
int res = n / 3;
int k = n % 3;
if(k == 0){
return pow(3,res);
}else if(k == 1){
return pow(3,res - 1)*4;
}else{
return pow(3,res)*k;
}
}
int pow(int m,int n){
int sum = 1;
while(n != 0){
if(n % 2 == 1){
sum = sum * m;
}
m = m * m;
n = n >> 1;
}
return sum;
}
}
class Solution:
def cuttingRope(self, n: int) -> int:
if n<=3:return n-1
sum =1
while n>4:
sum *=3
n -=3
return sum*n
class Solution:
def cuttingRope(self, n: int) -> int:
if n<4:return n-1
k,m = n//3,n%3
if m==0: return 3**k
elif m==1:return 3**(k-1)*4
else: return 3**k*2
class Solution {
//时间复杂度O(n)
//空间复杂度O(n)
public int cuttingRope(int n) {
int tem = 0;
for (int i = 2; i <= n; i++) {
if(multply(n,i) > tem){
tem = multply(n,i);
}
}
return tem;
}
public int function(int n,int i){
int sum = 1;
int tem = 1;
while(tem != 0){
if((i & tem) != 0) sum *= n;
tem <<= 1;
n *= n;
}
return sum;
}
public int multply(int n,int i){
int a = n / i;
int b = n % i;
if(b > 0){
return function(a+1,b) * function(a,i - b);
}else{
return function(a,i);
}
}
}
class Solution {
public int cuttingRope(int n) {
// 先判断特殊情况,等于2,3就不用再分了
if(n <=2) return 1;
if(n == 3) return 2;
//尽可能的把绳子分割成长度为3的子绳子,因为5以上包括5就得开始分割,2*4<=3*3.
//先求出能有多少个3
int res = n/3;
// 给3取余,得到余数
int mod = n%3;
int sum = 0;
// 等于0就直接返回就行
if(mod==0){
sum = F(3,res);
//等于1 就取出一个3,让它和余数3组成4,可使结果更大
}else if(mod == 1){
sum = F(3,res-1)*4;
// 等于2 直接与结果相乘
}else
sum = F(3,res) * 2;
return sum;
}
// n的res次方
public int F(int n,int res){
int sum = 1;
for(int i = 1;i<=res;i++){
sum*=n;
}
return sum;
}
}
class Solution {
public int cuttingRope(int n) {
if (n <= 2) {
return 1;
}
if (n == 3) {
return 2;
}
int res = n / 3;
int mod = n % 3;
if (mod == 0) {
return pow(3, res);
} else if (mod == 1) {
return pow(3, res - 1) * 4;
} else {
return pow(3, res) * 2;
}
}
public int pow(int m, int n) {
int res = 1;
for (int i = 0; i < n; i++) {
res *= m;
}
return res;
}
}
共以下 26 个回答
发现数学规律。动态规划也能做。
DP不咋会,看了题解
数学也不咋会
时间O(n) 空间O(1)
时间:O(1)
空间:O(1)
思路一:动态规划。对于长度为2的绳子,只能剪成1,1两段;对于长度为3的绳子,剪成1,2两段乘积最大,因为(11)1<2*1。时间复杂度O(N^2),空间复杂度O(1)。
思路二:动态规划。对于长度为i的绳子,两种情况,一种情况是剪去长度为j的绳子剩下长度为i-j的绳子(不继续剪),另一种情况是剪去长度为j的绳子剩下长度为i-j的绳子(继续剪)。时间复杂度O(N^2),空间复杂度O(1)。
思路三:数学知识。n>=5时尽可能把绳子剪成3的绳子段,当n4时剪成22,因为22>1*3。时间复杂度O(1),空间复杂度O(1)。
思路:数学推导可以得出:尽可能将绳子以长度 333 等分为多段时,乘积最大
算法流程:
(1)当 n≤3 时,按照规则应不切分,但由于题目要求必须剪成 m>1 段,因此必须剪出一段长度为 1的绳子,即返回 n−1 。
(2)当 n>3 时,求 n 除以3的 整数部分a和 余数部分b (即 n=3a+b),并分为以下三种情况:
dp:
注意: dp[i]的转移方程为dp[i] = max(dp[i], max(j * (i – j), j * dp[i – j]))
时间:O(n^2^)
空间:O(n)
动态规划
求次方采用快速幂时间复杂度为O(lgn),空间复杂度为O(1).
时间空间复杂度O(n)
时间/空间 O(1)
动规
数论
通过高数知识直接化简得到结果输出即可
时间/空间 O(1)
时间O(logn)
空间O(1)
//dp动态规划
class Solution {
public:
int integerBreak(int n) {
int dp[n+1];
for(int i=0;i<n+1;++i) dp[i]=0;
dp[2]=1;
for(int i=3;i<=n;++i){
for(int j=1;j<=i-2;++j){
dp[i]=max(dp[i],max(j(i-j),jdp[i-j]));
}
//dp[i]=max(dp[i],i-1);
}
return dp[n];
}
};
时间:O(1),空间:O(1)