Before we start, I want to confirm that all the returned values will always be in range [1,4] inclusively. Why is that? It is because we have Lagrange's Four Square Theorem, also known as Bachet's conjecture:
Every natural numbers can be expressed as a sum of four square numbers. (*)
The theorem is proved by Lagrange in 1770. To understand the proof, I suggest you read the provided link from Wiki. And later, the talented mathematician Ramanujan did a generalization on the theorem. I have to say it is extremely sad that Ramanujan's life was too short, even though his legacy is more than 3900 results (mostly identities and equations).
As a note, many proofs of the theorem use the Euler's four square identity:
Picture 1: Euler's Four Square Identity
Now I suggest you read this page. After reading it, you can solve this LeetCode problem mathematically! And you can also understand the algorithm to represent a natural number as a sum of four perfect squares!
Let me help you to summarize the related part of it.
From the article, you can find that if a number is in the form n = 4^r (8k+7) (Where ^ is power), then n cannot be represented as a sum of less than 4 perfect squares. If n is not in the above form, then n can be represented as a sum of 1, 2, or 3 perfect squares.
So now you know the basic theory behind, we can start coding!
I. Python Code
class Solution(object): def is_square(self, n): temp = int(math.sqrt(n)) return temp*temp == n def numSquares(self, n): """ :type n: int :rtype: int """ while n & 3 == 0: #n % 4 n = n >> 2 if n % 8 == 7: return 4 sqrt_n = int(math.sqrt(n)) if self.is_square(n): return 1 else: for i in range(1, sqrt_n+1): if self.is_square(n-i*i): return 2 return 3
II. Java Code
public class Solution { public boolean is_square(int n){ int temp = (int) Math.sqrt(n); return temp * temp == n; } public int numSquares(int n) { while ((n & 3) == 0) //n % 4 == 0 n >>= 2; if ((n & 7) == 7) return 4; //n% 8 == 7 if(is_square(n)) return 1; int sqrt_n = (int) Math.sqrt(n); for (int i = 1; i<= sqrt_n; i++){ if (is_square(n-i*i)) return 2; } return 3; } }
III. C++ Code
class Solution { public: int is_square(int n){ int temp = (int) sqrt(n); return temp * temp == n; } int numSquares(int n) { while ((n & 3) == 0) //n%4 == 0 n >>= 2; if ((n & 7) == 7) return 4; //n % 8 == 7 if(is_square(n)) return 1; int sqrt_n = (int) sqrt(n); for(int i = 1; i<= sqrt_n; i++){ if (is_square(n-i*i)) return 2; } return 3; } };
IV. Javascript Code
/** * @param {number} n * @return {number} */ var is_square = function(n){ var t = Math.floor(Math.sqrt(n)); return t * t == n; } var numSquares = function(n) { while ((n & 3) ===0) //n%4 == 0 n >>=2; if((n&7) == 7) return 4; //n % 8 = 7 if(is_square(n)) return 1; var sqrt_n = Math.floor(Math.sqrt(n)); for(var i=1; i<= sqrt_n; i++){ if(is_square(n-i*i)) return 2; } return 3; };