Minimum number of squares whose sum equals to a given number N | Set-3
A number can always be represented as a sum of squares of other numbers. Note that 1 is a square, and we can always break a number as (1*1 + 1*1 + 1*1 + …). Given a number n, find the minimum number of squares that sum to N.
Examples:
Input: N = 13
Output: 2
Explanation:
13 can be expressed as, 13 = 32 + 22. Hence, the output is 2.
Input: N = 100
Output: 1
Explanation:
100 can be expressed as 100 = 102. Hence, the output is 1.
Naive Approach: For [O(N*sqrt(N))] approach, please refer to Set 2 of this article.
Efficient Approach: To optimize the naive approach the idea is to use Lagrange’s Four-Square Theorem and Legendre’s Three-Square Theorem. The two theorems are discussed below:
Lagrange’s four-square theorem, also known as Bachet’s conjecture, states that every natural number can be represented as the sum of four integer squares, where each integer is non-negative.
Legendre’s three-square theorem states that a natural number can be represented as the sum of three squares of integers if and only if n is not of the form : n = 4a (8b+7), for non-negative integers a and b.
Therefore, it is proved that the minimum number of squares to represent any number N can only be within the set {1, 2, 3, 4}. Thus, only checking for these 4 possible values, the minimum number of squares to represent any number N can be found. Follow the steps below:
- If N is a perfect square, then the result is 1.
- If N can be expressed as the sum of two squares, then the result is 2.
- If N cannot be expressed in the form of N = 4a (8b+7), where a and b are non-negative integers, then the result is 3 by Legendre’s three-square theorem.
- If all the above conditions are not satisfied, then by Lagrange’s four-square theorem, the result is 4.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool isPerfectSquare( int N)
{
int floorSqrt = sqrt (N);
return (N == floorSqrt * floorSqrt);
}
bool legendreFunction( int N)
{
while (N % 4 == 0)
N /= 4;
if (N % 8 != 7)
return true ;
else
return false ;
}
int minSquares( int N)
{
if (isPerfectSquare(N))
return 1;
for ( int i = 1; i * i < N; i++) {
if (isPerfectSquare(N - i * i))
return 2;
}
if (legendreFunction(N))
return 3;
return 4;
}
int main()
{
int N = 123;
cout << minSquares(N);
return 0;
}
|
Java
import java.util.*;
class GFG{
static boolean isPerfectSquare( int N)
{
int floorSqrt = ( int )Math.sqrt(N);
return (N == floorSqrt * floorSqrt);
}
static boolean legendreFunction( int N)
{
while (N % 4 == 0 )
N /= 4 ;
if (N % 8 != 7 )
return true ;
else
return false ;
}
static int minSquares( int N)
{
if (isPerfectSquare(N))
return 1 ;
for ( int i = 1 ; i * i < N; i++)
{
if (isPerfectSquare(N - i * i))
return 2 ;
}
if (legendreFunction(N))
return 3 ;
return 4 ;
}
public static void main(String[] args)
{
int N = 123 ;
System.out.print(minSquares(N));
}
}
|
Python3
from math import sqrt, floor, ceil
def isPerfectSquare(N):
floorSqrt = floor(sqrt(N))
return (N = = floorSqrt * floorSqrt)
def legendreFunction(N):
while (N % 4 = = 0 ):
N / / = 4
if (N % 8 ! = 7 ):
return True
else :
return False
def minSquares(N):
if (isPerfectSquare(N)):
return 1
for i in range (N):
if i * i < N:
break
if (isPerfectSquare(N - i * i)):
return 2
if (legendreFunction(N)):
return 3
return 4
if __name__ = = '__main__' :
N = 123
print (minSquares(N))
|
C#
using System;
class GFG{
static bool isPerfectSquare( int N)
{
int floorSqrt = ( int )Math.Sqrt(N);
return (N == floorSqrt * floorSqrt);
}
static bool legendreFunction( int N)
{
while (N % 4 == 0)
N /= 4;
if (N % 8 != 7)
return true ;
else
return false ;
}
static int minSquares( int N)
{
if (isPerfectSquare(N))
return 1;
for ( int i = 1; i * i < N; i++)
{
if (isPerfectSquare(N - i * i))
return 2;
}
if (legendreFunction(N))
return 3;
return 4;
}
public static void Main(String[] args)
{
int N = 123;
Console.Write(minSquares(N));
}
}
|
Javascript
<script>
function isPerfectSquare(N)
{
let floorSqrt = Math.floor(Math.sqrt(N));
return (N == floorSqrt * floorSqrt);
}
function legendreFunction(N)
{
while (N % 4 == 0)
N = Math.floor(N / 4);
if (N % 8 != 7)
return true ;
else
return false ;
}
function minSquares(N)
{
if (isPerfectSquare(N))
return 1;
for (let i = 1; i * i < N; i++)
{
if (isPerfectSquare(N - i * i))
return 2;
}
if (legendreFunction(N))
return 3;
return 4;
}
let N = 123;
document.write(minSquares(N));
</script>
|
Time Complexity: O(sqrt(N))
Auxiliary Space: O(1)
Last Updated :
11 May, 2021
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...