• 279 Perfect Squares 完美平方数


    给定正整数 n,找到若干个完全平方数(比如 1, 4, 9, 16, ...) 使得他们的和等于 n。你需要让平方数的个数最少。
    比如 n = 12,返回 3 ,因为 12 = 4 + 4 + 4 ; 给定 n = 13,返回 2 ,因为 13 = 4 + 9。

    详见:https://leetcode.com/problems/perfect-squares/description/

    Java实现:

    方法一:递归实现

    class Solution {
        public int numSquares(int n) {
            int res = n, num = 2;
            while (num * num <= n) {
                int a = n / (num * num), b = n % (num * num);
                res = Math.min(res, a + numSquares(b));
                ++num;
            }
            return res;
        }
    }
    

     方法二:动态规划

    如果一个数x可以表示为一个任意数a加上一个平方数bxb,也就是x=a+bxb,那么能组成这个数x最少的平方数个数,就是能组成a最少的平方数个数加上1(因为b*b已经是平方数了)。

    class Solution {
        public int numSquares(int n) {
            int[] dp = new int[n+1];
            // 将所有非平方数的结果置最大,保证之后比较的时候不被选中
            Arrays.fill(dp, Integer.MAX_VALUE);
            // 将所有平方数的结果置1
            for(int i = 0; i * i <= n; i++){
                dp[i * i] = 1;
            }
            // 从小到大找任意数a
            for(int a = 0; a <= n; a++){
                // 从小到大找平方数bxb
                for(int b = 0; a + b * b <= n; b++){
                    // 因为a+b*b可能本身就是平方数,所以我们要取两个中较小的
                    dp[a + b * b] = Math.min(dp[a] + 1, dp[a + b * b]);
                }
            }
            return dp[n];
        }
    }
    

    C++实现:

    方法一:

    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)
            {
                int b=sqrt(n-a*a);
                if(a*a+b*b==n)
                {
                    return !!a+!!b;
                }
            }
            return 3;
        }
    };
    

     方法二:

    class Solution {
    public:
        int numSquares(int n) {
            vector<int> dp(n+1,INT_MAX);
            dp[0]=0;
            for(int i=0;i<=n;++i)
            {
                for(int j=1;i+j*j<=n;++j)
                {
                    dp[i+j*j]=min(dp[i+j*j],dp[i]+1);
                }
            }
            return dp.back();
        }
    };
    

     方法三:

    class Solution {
    public:
        int numSquares(int n) {
            vector<int> dp(1, 0);
            while (dp.size() <= n) 
            {
                int m = dp.size(), val = INT_MAX;
                for (int i = 1; i * i <= m; ++i)
                {
                    val = min(val, dp[m - i * i] + 1);
                }
                dp.push_back(val);
            }
            return dp.back();
        }
    };
    

     参考:https://www.cnblogs.com/grandyang/p/4800552.html

  • 相关阅读:
    哈希表(hash)
    并查集
    trie树(字典树)
    单调队列(滑动窗口)
    单调栈
    用数组实现栈与队列
    数组实现双链表
    数组实现单链表
    区间合并
    离散化
  • 原文地址:https://www.cnblogs.com/xidian2014/p/8762034.html
Copyright © 2020-2023  润新知