Skip to content

Latest commit

 

History

History
64 lines (55 loc) · 2.18 KB

File metadata and controls

64 lines (55 loc) · 2.18 KB

题目

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

示例 1:

输入: n = 12 输出: 3 解释: 12 = 4 + 4 + 4

思路

  • 我的:广度优先,队列的元素是所有小于sqrt(n)的完全平方数累加。每次都需要遍历所有小于n的平方根的完全平方数进行累加,结果导致超时。
int numSquares(int n) {
        vector<int> a;
        if(sqrt(n)==int(sqrt(n))) return 1;
        queue<int> q;
        for(int i = 1; i <= sqrt(n) ; i++){
          a.push_back(pow(i,2));
          q.push(pow(i,2));
          
        }   
        int step = 0;
        while(!q.empty()){
            step ++;
            int size = q.size();
            for(int i=0;i<size;i++) {
                int cur = q.front();
                if(cur==n) return step;
                if(cur>n){q.pop();}
                if(cur<n){
                    for(int j=0;j<a.size();j++){
                        int sum = cur+a[j];
                        if( sum <= n ){
                            q.push(sum);  
                        } else {
                        	break;
                        }
                        
                    }
                }
                q.pop();
            }
        }
    }
  • 别人的:动态规划。每个非完全平方数,可以当作是一个完全平方数+一个普通数。所以可以维持一个n+1的数组dp,dp[i]代表达到i最少需要的完全平方数数量。关键的转移方程为:dp[i+j * j] = min(dp[i+j * j],dp[i]+1); 意思是如果这个元素是完全平方数则取dp[i+j*j],否则取dp[i]+1。这个动态规划的子问题的范围是两个相邻完全平方数之间的数。

图片

 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[n];
 }