Xiaohe-LeetCode 279 Perfect Squares

(1)Best way.94%

This one uses Lagrange's four-square theorem.

According to it, every integer is a sum of at most 4 perfect square numbers. Therefore the result should be one of 1,2,3,4. 

class Solution {
  public:
  int numSquares(int n) {
    while (n % 4 == 0) n /= 4;//no effect on result, but simplified calculate.
    if (n % 8 == 7) return 4;//by theorem.
    for (int a = 0; a * a <= n; ++a) {
    int b = sqrt(n - a * a);
    if (a * a + b * b == n)

    {
    return !!a + !!b;//!!is to find out if a,b is 0 or 1.
    }
  }
    return 3;
}
};


(2)DP: 

Actually the 2 ways below use the same method. The only difference is they use different containers. One uses hmap, another one uses vector. But the result of time has a great difference.I do not know why, and hope someone can answer.

class Solution {
  public:
    int numSquares(int n) {
      unordered_map<int,int> hmap;
      if(n==1)
      return 1;
      hmap[0]=0;
      for(int m=1;m<=n;m++)
      {
        int minval=INT_MAX;
        for(int j=1;j*j<=m;j++)
        {
        hmap[j*j]=1;
        minval=min(minval,hmap[j*j]+hmap[m-j*j]);
        }
       hmap[m]=minval;
      }
       return hmap[n];
  }
};

This one is not good. Time Limit Exceeded, time 5673ms.

Let's see another one.

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

This one is better. 46% and runing time is 320ms.

原文地址:https://www.cnblogs.com/CathyXiaohe/p/4985374.html