279. Perfect Squares 最少数量的平方和

Given a positive integer n, find the least number of perfect square numbers (for example, 1, 4, 9, 16, ...) which sum to n.

Example 1:

Input: n = 12
Output: 3 
Explanation: 12 = 4 + 4 + 4.

Example 2:

Input: n = 13

Output: 2
Explanation: 13 = 4 + 9.

题意:求给出的数最少能由几个数的平方和组成。

思路:给出一个数x(x=y^2+z),求它的最少数量的平方和,此时若z的最少数量的平方和已经求出,则x的最少数量的平方和=z的最少数量的平方和+1;

例如x=13,当y=1时,z=12,由给出的示例可知 leastNums[12]=3,所以leastNums[13]=leastNums[12]+1 = 4;

当y=2时,z=9,9=3*3,所以 leastNums[9]=1,leastNums[13]=leastNums[9]+1 = 2;

当y=3时,z=4,4=2*2,所以 leastNums[4]=1,leastNums[13]=leastNums[4]+1 = 2。

使用动态规划的方法, 从1开始一直到n,算出每个数至少能由几个数的平方和组成。

代码:

class Solution {
    public int numSquares(int n) {
        if(n<=0)
            return 0;

        int[] leastNums = new int[n+1];
        leastNums[0]=0;  //x=y*y+z,若z=0,则leastNums[x]=leastNums[0]+1

        for(int i =1;i<=n;i++){
            int minNum = Integer.MAX_VALUE; //默认值为INT最大值

            for(int j=1;j*j<=i;j++){

                //leastNums[x]=leastNums[z]+1
                minNum = Math.min(minNum,leastNums[i - j*j]+1);
            }

            leastNums[i] = minNum;
        }

        return leastNums[n];
    }
}

还有一种用数学公式求的方法(c++):

class Solution 
{  
private:  
    int is_square(int n)
    {  
        int sqrt_n = (int)(sqrt(n));  
        return (sqrt_n*sqrt_n == n);  
    }
    
public:
    // Based on Lagrange's Four Square theorem, there 
    // are only 4 possible results: 1, 2, 3, 4.
    int numSquares(int n) 
    {  
        // If n is a perfect square, return 1.
        if(is_square(n)) 
        {
            return 1;  
        }
        
        // The result is 4 if and only if n can be written in the 
        // form of 4^k*(8*m + 7). Please refer to 
        // Legendre's three-square theorem.
        while ((n & 3) == 0) // n%4 == 0  
        {
            n >>= 2;  
        }
        if ((n & 7) == 7) // n%8 == 7
        {
            return 4;
        }
        
        // Check whether 2 is the result.
        int sqrt_n = (int)(sqrt(n)); 
        for(int i = 1; i <= sqrt_n; i++)
        {  
            if (is_square(n - i*i)) 
            {
                return 2;  
            }
        }  
        
        return 3;  
    }  
}; 

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值