【LeetCode】279完全平方数

 

思路:动态规划,最初想到的公式是:

后来提交之后报出超时错误,因此参考了题解,找到正确的公式为:

第二个公式直接计算“前段”为平方数的情况,比起第一个公式,时间复杂度从n^2降低到n^1.5;

因此,仅仅写出动态规划的公式是不够的,需要保证:

(1)公式的正确性;

(2)公式的高效性,此一条跟题目有关。

详细分析题目中可以用来降低时间复杂度的题点,吃一堑长一智~。

代码1. 循环写法:

    public int numSquares(int n){
        if(n<=0) return 0;
        int[] fn=new int[n+1];
        fn[0]=0;
        fn[1]=1;

        //填充数组的过程
        for(int i=2;i<n+1;i++){
            int min=i;
            for(int j=1;j*j<=i;j++){
                if(min>1+fn[i-j*j]) {
                    min = 1 + fn[i - j * j];
                }
            }
            fn[i]=min;
        }

        return fn[n];
    }

代码2. 递归写法:

    public static int numSquares(int n) {
        if(n<=0) return 0;
        int[] fn=new int[n+1];
        fn[0]=0;
        fn[1]=1;
        //开始递归
        numSquaresCore(n,fn);
        //获得结果
        int answer=fn[n];
        return answer;
    }

    public static int numSquaresCore(int index,int[] fn){
        //解决已知情况
        if(index<=0) return 0;
        if(index==1) return 1;
        if(fn[index]!=0) return fn[index];

        //最大不会超过index个,就是index=1+1+...+1的情况
        int min=index;
        int border=(int)(Math.pow(index,0.5)+0.5);
        for(int i=1;i<=border;i++){
            if(index-i*i==0){
                //当前为平方数
                min=1;
            }
            else if(index-i*i>0){
                //减掉i*i,然后计算剩余的子问题
                if(fn[index-i*i]==0){
                    fn[index-i*i]=numSquaresCore(index-i*i,fn);
                }
                if(min>1+fn[index-i*i]){
                    min=1+fn[index-i*i];
                }
            }
        }

        fn[index]=min;
        return min;
    }

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值