力扣完全平方数(难度:中等)

题目

题目解读:

        题目很显然是要我们返回一个数的由最小平方数组成的数量,这道题乍一看很难,但是我们仔细想想,假设n=4,用result来表示最小数量,当遍历到n为1时,1本身就是完全平方数,所以result为1;当遍历到n为2时,2当中只有1是完全平方数,所以result为1+1=2;当n=3时,当然就是1+1+1=3啦,重点是n为4时,因为4本身就为完全平方数(2的平方),所以result为1,此时与当n为1的结果是一样的。

        那我们可不可以把每个数的最小结果数给存储起来,如果当n为60的时候,可以表示为36+24,此时我们只要知道当n为24时的最小结果数再加上1(36=6*6)那么就是60的结果啦。

        有经验的小伙伴就知道这是动态规划!用局部最优解来联系整体最优解。

代码部分

状态转移方程解读:

       一般都是用数学归纳法进行整理出方程。

        因为要存储到dp[n],所以dp[0]可以设置为0,也可以不设置。因为在java中数组默认为0

当n = 12时,我们需要计算f[12]的值。

首先,初始化数组f,长度为n+1,即长度为13。

然后,我们使用一个循环从1到12来计算f[i]的值。

前提:dp[i] = i;这是一个最坏判断,意味着全部都是由1构成。

当i=1,j=1时,dp[1]=1;

当i=2,j=1时,dp[2]与dp[2-1]+1进行比较,dp[2] = 2;

当i=3,j=1时,dp[3]与dp[3-1]+1进行比较,dp[3] = 3; 

当i=4,j=1时,dp[4]与dp[4-1]+1进行比较,dp[4] = 4;

当i=4,j=2时,dp[4]与dp[4-4]+1进行比较,dp[4] = 1;

...同理,就是利用当前最优解来联系整体进行求解  

通过这个状态转移方程,我们可以逐步计算出f[1]、f[2]、f[3]、...、f[n]的值,最终得到f[n]的最小值作为结果。

 public int numSquares(int n) {
      int [] dp = new int [n+1]; //因为遍历是从1开始从n结束,每个数组都要存储当前最小结果数
      for(int i=1;i<=n;i++){
          dp[i]=i;//最坏结果,每个数都是由完全平方数1构成
          for(int j=1;j*j<=i;j++){//将遍历对象限制为小于i的平方数
              dp[i]=Math.min(dp[i],dp[i-j*j]+1);//状态转移方程
          }
      }
      return dp[n];
     }

 

  • 7
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值