leetcode 279 完全平方数

对于一个整数,求其最小用几个完全平方数相加得到。算是动态规划的办法,求出从大到小所有数的最小平方数和个数,最后返回结果即可。小细节就是判断最小个数时,记最大的平方小于当前数的数为sqrtN,需要从n-sqrtN*sqrtN判断到n-(sqrtN/2)*sqrtN/2),之后就不需要再向下判断,因为如果变为sqrtN的一半,需要四个这样的完全平方数才和原来的一个大小相同,毫无必要。可以减少一定的复杂度。贴代码

 1 class Solution {
 2 public:
 3     int numSquares(int n) 
 4     {
 5         int sqrtN = sqrt(double(n));
 6         //cout<<sqrtN<<endl;
 7         vector<int> numSq(n+1,0);
 8         for(int i = 0 ; i <= n ; i++)
 9         numSq[i] = i;
10         for(int i = 1 ; i <= sqrtN ; i++)
11         {
12             int sq = i*i;
13             numSq[sq] = 1;
14             for(int j = (i-1)*(i-1)+1 ; j < sq ; j++)
15             {
16                 int minSize = numSq[j];
17                 for(int k = i-1 ; k >= i/2 ; k--)
18                 {
19                     if(1+numSq[j-k*k]<minSize)
20                     minSize = 1+numSq[j-k*k];
21                 }
22                 numSq[j] = minSize;
23             }
24         }
25         for(int i = sqrtN*sqrtN+1 ; i <= n ; i++)
26         {
27             int minSize = numSq[i];
28             for(int k = sqrtN ; k >= sqrtN/2 ; k--)
29             {
30                 if((1+numSq[i-k*k])<minSize)
31                 minSize = 1+numSq[i-k*k];
32             }
33             numSq[i] = minSize;
34         }
35         return numSq[n];
36     }
37 };

四平方和定理,每个正整数都可以表示为4个整数的平方和,并且n = 4^n * (8m+7)时,该数只能被表示为四个整数的平方和,剩余的数都可表示为3个数以下的平方和。所以可以把问题转化成,首先判断是否满足上述公式,如果是,则返回4,如果不是,判断是否为平方数或者为两个平方数之和, 如果不是,则肯定是3个数的平方和,则完成任务。

posted @ 2021-11-14 12:03  zhaohhhh  阅读(47)  评论(0)    收藏  举报