LeetCode-【动态规划】-完全平方数

版权声明:转载注明出处就可以了。。。 https://blog.csdn.net/zw159357/article/details/82595031

给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...)使得它们的和等于 n。你需要让组成和的完全平方数的个数最少。

示例 1:

输入: n = 12

输出: 3 
解释: 12 = 4 + 4 + 4.

示例 2:

输入: n = 13

输出: 2
解释: 13 = 4 + 9.

题解:最基本的思路,先列举一定数量的数据,看看是否能够找到规律,呵呵,恰巧本题有规律。

1 1
2 1 1
3 1 1 1
4 4
5 1 4
6 1 1 4
7 1 1 1 4
8 4 4
9 9
10 1 9
11 1 1 9
12 4 4 4
13 4 9
14 1 4 9
15 1 1 4 9
16 16

根据这个可以发现组成数字的完全平方数的个数不会超过四个,如果是能够被4整除的,都等于不断除以4,直至不让被4整除后余下的那个数对应的完全平方个数,比如16等于1,12等于3,4等于1.;如果n取余8余7,那么它的最少的完全平方数一定是4;完全平方数是2的就得通过循环判断了,剩下的就完全平方数为3的了。

class Solution {
    public int numSquares(int n) {
        while(n%4==0)
            n/=4;
        if(n%8==7)
            return 4;
        for(int a=0;a*a<=n;a++)
            if(n==a*a)
                return 1;
        for(int a=0;a*a<=n;a++){
            int b=(int)(Math.sqrt(n-a*a));
            if(a*a+b*b==n&&a>=0&&b>=0)
                return 2;
        }
        return 3;
    }
}

动规解法:对一个数字n而言,组成的它的完全平方数的最少个数可以根据它减去i*i(这里i*i<n)后对应的那个数的最少完全平方数加一,通过改变i的值最终取得最小值。

还是从简单情况开始
1   1>=1*1 所以1对应等于0对应的最小个数加1,这里0对应的个数为0
2   2>=1*1 所以2对应等于1对应的最小个个数加1,因为之前已经记录了1对应的最小值为1,所以这里最小为2
3   3>=1*1 所以3对应等于2对应的最小个个数加1,因为之前已经记录了2对应的最小值为1,所以这里最小为3
4   4>=1*1和4>=4 所以4对应等于3或者0对应的最小个个数加1,因为之前已经记录了3对应的最小值为3,0对应的最小值为0,所以最终的最小值为1。
往后的情况依次类推。。。

class Solution {
    public int numSquares(int n) {
        int [] dp=new int[n+1];
        Arrays.fill(dp,1000000);
        dp[0]=0;
        for(int i=1;i<=n;i++){
            int j=1;
            while(i-j*j>=0){
                dp[i]=Math.min(dp[i],dp[i-j*j]+1);
                j++;
            }
        }
        return dp[n];
    }
}

猜你喜欢

转载自blog.csdn.net/zw159357/article/details/82595031