class Solution { public int minSteps(int n) { int[] dp=new int[n+1]; dp[0]=0; for(int i=1;i<=n;i++){ dp[i]=i; for(int k=1;k<n/2;k++){ if(i%k==0){ dp[i]=Math.min(dp[i],dp[k]+(i/k)); } } } return n==1?0:dp[n]; } }
用dp做,得到长度为i的字符串操作次数最长是i次,但实际上可以优化,比如dp[8]可以用dp[2]加上8/2(复制一次,粘贴3次)或者dp[4]加上8/4 那么每计算一个dp[i]就从头开始遍历,不断找到最小值。
方法比较笨,是第一时间想到的,注意n=1的情况
优化版本来了,考虑素数和的情况可以进行优化:
class Solution { public int minSteps(int n) { if(n==1) return 0; int[] dp=new int[n+1]; dp[0]=0; dp[1]=0; int h=(int)Math.sqrt(n); for(int i=2;i<=n;i++){ dp[i]=i; for(int k=2;k<=h;k++){ if(i%k==0){ dp[i]=dp[k]+dp[i/k]; break; } } } return dp[n]; } }
找到第一个可以被i整除的素数就返回,dp[i]的结果一定是i所能被分解的素数和的形式。