Minimum Perfect Squares that sums to N
Last Updated :
06 Nov, 2025
Given a positive integer n, find the minimum number of perfect squares that sum up to n. We can use each square any number of times.
Note: A number can always be represented as a sum of squares of other numbers. Because 1 is a square number and we can always break any number as (12 + 12 + 12 + ... ).
Examples :
Input: n = 100
Output: 1
Explanation: 100 can be written as [102] or [52 + 52 + 52 + 52] and the minimum number of perfect squares needed for 100 is 1.
Input: n = 6
Output: 3
Explanation: Only possible way to make sum equals to 6 is [12 + 12 + 22], so minimum square numbers needed is 3.
[Naive Approach] - Using Recursion
In this approach, we solve the problem recursively by exploring all possible ways to form the number using perfect squares. For a given number n, we try subtracting every possible perfect square that is less than or equal to n.
For each subtraction, we recursively compute the minimum number of squares required to represent the remaining value. Among all these possibilities, we take the minimum result.
C++
//Driver Code Starts
#include <iostream>
#include <cmath>
using namespace std;
//Driver Code Ends
int minSquares(int n) {
// minSquares(0) = 0
if (n == 0)
return 0;
// n = 1*1 + 1*1 .... n times
// so we can initialise count with n
int cnt = n;
// Go through all smaller numbers
// to recursively find minimum
for (int x = 1; x * x <= n; x++) {
cnt = min(cnt, 1 + minSquares(n - x * x));
}
return cnt;
}
//Driver Code Starts
int main() {
int n = 6;
cout << minSquares(n) << endl;
return 0;
}
//Driver Code Ends
C
//Driver Code Starts
#include <stdio.h>
#include <math.h>
//Driver Code Ends
int minSquares(int n) {
// minSquares(0) = 0
if (n == 0)
return 0;
// n = 1*1 + 1*1 .... n times
// so we can initialise count with n
int cnt = n;
// Go through all smaller numbers
// to recursively find minimum
for (int x = 1; x * x <= n; x++) {
int temp = 1 + minSquares(n - x * x);
if (temp < cnt)
cnt = temp;
}
return cnt;
}
//Driver Code Starts
int main() {
int n = 6;
printf("%d
", minSquares(n));
return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
class GFG {
//Driver Code Ends
static int minSquares(int n) {
// minSquares(0) = 0
if (n == 0)
return 0;
// n = 1*1 + 1*1 .... n times
// so we can initialise count with n
int cnt = n;
// Go through all smaller numbers
// to recursively find minimum
for (int x = 1; x * x <= n; x++) {
cnt = Math.min(cnt, 1 + minSquares(n - x * x));
}
return cnt;
}
//Driver Code Starts
public static void main(String[] args) {
int n = 6;
System.out.println(minSquares(n));
}
}
//Driver Code Ends
Python
def minSquares(n):
# minSquares(0) = 0
if n == 0:
return 0
# n = 1*1 + 1*1 .... n times
# so we can initialise count with n
cnt = n
x = 1
# Go through all smaller numbers
# to recursively find minimum
while x * x <= n:
cnt = min(cnt, 1 + minSquares(n - x * x))
x += 1
return cnt
if __name__ == "__main__":
#Driver Code Starts
n = 6
print(minSquares(n))
#Driver Code Ends
C#
//Driver Code Starts
using System;
class GFG {
//Driver Code Ends
static int minSquares(int n) {
// minSquares(0) = 0
if (n == 0)
return 0;
// n = 1*1 + 1*1 .... n times
// so we can initialise count with n
int cnt = n;
// Go through all smaller numbers
// to recursively find minimum
for (int x = 1; x * x <= n; x++) {
cnt = Math.Min(cnt, 1 + minSquares(n - x * x));
}
return cnt;
}
//Driver Code Starts
static void Main() {
int n = 6;
Console.WriteLine(minSquares(n));
}
}
//Driver Code Ends
JavaScript
function minSquares(n) {
// minSquares(0) = 0
if (n === 0)
return 0;
// n = 1*1 + 1*1 .... n times
// so we can initialise count with n
let cnt = n;
// Go through all smaller numbers
// to recursively find minimum
for (let x = 1; x * x <= n; x++) {
cnt = Math.min(cnt, 1 + minSquares(n - x * x));
}
return cnt;
}
// Driver code
//Driver Code Starts
let n = 6;
console.log(minSquares(n));
//Driver Code Ends
Time Complexity: O(nn), for every n we make sqrt(n) function calls.
Auxiliary Space: O(n) - recursive stack space
[Better Approach - 1] - Using Top-Down DP (Memoization)
In this approach, we notice that many subproblems overlap because multiple larger subproblems depend on and call the same smaller subproblems, that lead to the same computation being done again and again. In order to avoid this redundant computation, we can store the results of subproblems in a dp array and reuse them whenever needed.
C++
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends
int minSquaresRec(int n, vector<int>& dp) {
// base case
if (n == 0)
return 0;
// if the result for this subproblem is
// already computed then return it
if (dp[n] != -1)
return dp[n];
// n = 1*1 + 1*1 .... n times
// so we can initialise count with n
int cnt = n;
// Go through all smaller numbers
// to recursively find minimum
for (int x = 1; x*x <= n; x++) {
cnt = min(cnt, 1 + minSquaresRec(n - x*x, dp));
}
// store the result of this problem
return dp[n] = cnt;
}
int minSquares(int n) {
// dp array to store the results
vector<int> dp(n + 1, -1);
return minSquaresRec(n, dp);
}
//Driver Code Starts
int main() {
int n = 6;
cout << minSquares(n);
return 0;
}
//Driver Code Ends
C
//Driver Code Starts
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
//Driver Code Ends
int minSquaresRec(int n, int dp[]) {
// base case
if (n == 0)
return n;
// if the result for this subproblem is already
// computed then return it
if (dp[n] != -1)
return dp[n];
// n = 1*1 + 1*1 .... n times
// so we can initialise count with n
int cnt = n;
// Go through all smaller numbers
// to recursively find minimum
for (int x = 1; x * x <= n; x++) {
int temp = 1 + minSquaresRec(n - x * x, dp);
if (temp < cnt)
cnt = temp;
}
// store the result of this problem
dp[n] = cnt;
return cnt;
}
int minSquares(int n) {
// dp array to store the results
int* dp = (int*)malloc((n + 1) * sizeof(int));
for (int i = 0; i <= n; i++)
dp[i] = -1;
int result = minSquaresRec(n, dp);
free(dp);
return result;
}
//Driver Code Starts
int main() {
int n = 6;
printf("%d
", minSquares(n));
return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;
class GFG {
//Driver Code Ends
static int minSquaresRec(int n, int[] dp) {
// base case
if (n == 0)
return n;
// if the result for this subproblem is
// already computed then return it
if (dp[n] != -1)
return dp[n];
// n = 1*1 + 1*1 .... n times
// so we can initialise count with n
int cnt = n;
// Go through all smaller numbers
// to recursively find minimum
for (int x = 1; x * x <= n; x++) {
cnt = Math.min(cnt, 1 + minSquaresRec(n - x * x, dp));
}
// store the result of this problem
return dp[n] = cnt;
}
static int minSquares(int n) {
// dp array to store the results
int[] dp = new int[n + 1];
Arrays.fill(dp, -1);
return minSquaresRec(n, dp);
}
//Driver Code Starts
public static void main(String[] args) {
int n = 6;
System.out.println(minSquares(n));
}
}
//Driver Code Ends
Python
def minSquaresRec(n, dp):
# base case: minSquares(0) = 0
if n == 0:
return n
# if the result for this subproblem is already
# computed then return it
if dp[n] != -1:
return dp[n]
# n = 1*1 + 1*1 .... n times
# so we can initialise count with n
cnt = n
# Go through all smaller numbers
# to recursively find minimum
for x in range(1, int(n**0.5) + 1):
cnt = min(cnt, 1 + minSquaresRec(n - x * x, dp))
# store the result of this problem
dp[n] = cnt
return cnt
def minSquares(n):
# dp array to store the results
dp = [-1] * (n + 1)
return minSquaresRec(n, dp)
#Driver Code Starts
if __name__ == "__main__":
n = 6
print(minSquares(n))
#Driver Code Ends
C#
//Driver Code Starts
using System;
class GFG {
//Driver Code Ends
static int minSquaresRec(int n, int[] dp) {
// base case
if (n == 0)
return n;
// if the result for this subproblem is already
// computed then return it
if (dp[n] != -1)
return dp[n];
// n = 1*1 + 1*1 .... n times
// so we can initialise count with n
int cnt = n;
// Go through all smaller numbers
// to recursively find minimum
for (int x = 1; x * x <= n; x++) {
cnt = Math.Min(cnt, 1 + minSquaresRec(n - x * x, dp));
}
// store the result of this problem
return dp[n] = cnt;
}
static int minSquares(int n) {
// dp array to store the results
int[] dp = new int[n + 1];
Array.Fill(dp, -1);
return minSquaresRec(n, dp);
}
//Driver Code Starts
static void Main() {
int n = 6;
Console.WriteLine(minSquares(n));
}
}
//Driver Code Ends
JavaScript
function minSquaresRec(n, dp) {
// base case
if (n == 0)
return n;
// if the result for this subproblem is already
// computed then return it
if (dp[n] !== -1)
return dp[n];
// n = 1*1 + 1*1 .... n times
// so we can initialise count with n
let cnt = n;
// Go through all smaller numbers
// to recursively find minimum
for (let x = 1; x * x <= n; x++) {
cnt = Math.min(cnt, 1 + minSquaresRec(n - x * x, dp));
}
// store the result of this problem
return dp[n] = cnt;
}
function minSquares(n) {
// dp array to store the results
const dp = Array(n + 1).fill(-1);
return minSquaresRec(n, dp);
}
// Driver code
//Driver Code Starts
const n = 6;
console.log(minSquares(n));
//Driver Code Ends
Time Complexity: O(n*sqrt(n)), as we compute each subproblem only once using memoization.
Auxiliary Space: O(n)
[Better Approach - 2] - Using Bottom-Up DP (Tabulation)
In this approach, we are iteratively calculating the answers beginning with the smallest subproblems — base cases. Using these base values, we then find the answers for larger numbers one by one. For each number, we check for all smaller subproblems(obtained by subtracting a perfect square from current number) to find the minimum count.
C++
//Driver Code Starts
#include <iostream>
#include <vector>
using namespace std;
//Driver Code Ends
int minSquares(int n) {
// Memoization array to store the results
vector<int> dp(n + 1);
// base cases
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = i;
for (int x = 1; x * x <= i; ++x) {
// recursive case
dp[i] = min(dp[i], 1 + dp[i - x*x]);
}
}
return dp[n];
}
//Driver Code Starts
int main() {
int n = 6;
cout << minSquares(n);
return 0;
}
//Driver Code Ends
C
//Driver Code Starts
#include <stdio.h>
#include <stdlib.h>
//Driver Code Ends
int minSquares(int n) {
// Memoization array to store the results
int* dp = (int*)malloc((n + 1) * sizeof(int));
// base cases
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = i;
for (int x = 1; x * x <= i; ++x) {
// recursive case
int temp = 1 + dp[i - x * x];
if (temp < dp[i])
dp[i] = temp;
}
}
int result = dp[n];
free(dp);
return result;
}
//Driver Code Starts
int main() {
int n = 6;
printf("%d", minSquares(n));
return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
import java.util.Arrays;
class GFG {
//Driver Code Ends
static int minSquares(int n) {
// Memoization array to store the results
int[] dp = new int[n + 1];
// base cases
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = i;
for (int x = 1; x * x <= i; ++x) {
// recursive case
dp[i] = Math.min(dp[i], 1 + dp[i - x * x]);
}
}
return dp[n];
}
//Driver Code Starts
public static void main(String[] args) {
int n = 6;
System.out.println(minSquares(n));
}
}
//Driver Code Ends
Python
def minSquares(n):
# Memoization array to store the results
dp = [0] * (n + 1)
# base cases
dp[0] = 0
dp[1] = 1
for i in range(2, n + 1):
dp[i] = i
for x in range(1, int(i**0.5) + 1):
# recursive case
dp[i] = min(dp[i], 1 + dp[i - x * x])
return dp[n]
#Driver Code Starts
if __name__ == "__main__":
n = 6
print(minSquares(n))
#Driver Code Ends
C#
//Driver Code Starts
using System;
class GFG {
//Driver Code Ends
static int minSquares(int n) {
// Memoization array to store the results
int[] dp = new int[n + 1];
// base cases
dp[0] = 0;
dp[1] = 1;
for (int i = 2; i <= n; i++) {
dp[i] = i;
for (int x = 1; x * x <= i; ++x) {
// recursive case
dp[i] = Math.Min(dp[i], 1 + dp[i - x * x]);
}
}
return dp[n];
}
//Driver Code Starts
static void Main() {
int n = 6;
Console.WriteLine(minSquares(n));
}
}
//Driver Code Ends
JavaScript
function minSquares(n) {
// Memoization array to store the results
let dp = new Array(n + 1);
// base cases
dp[0] = 0;
dp[1] = 1;
for (let i = 2; i <= n; i++) {
dp[i] = i;
for (let x = 1; x * x <= i; x++) {
// recursive case
dp[i] = Math.min(dp[i], 1 + dp[i - x * x]);
}
}
return dp[n];
}
// Driver Code
//Driver Code Starts
let n = 6;
console.log(minSquares(n));
//Driver Code Ends
Time Complexity: O(n*sqrt(n))
Auxiliary Space: O(n), used for dp[] array.
[Better Approach - 3] - Using Breadth-First Search
In this approach, we iteratively find the minimum steps required to reach smaller values by subtracting perfect squares at each step, solving any subproblem we haven’t solved yet until we reach 0.
This can be visualized as a graph where the vertices are numbered from 0 to n, and there is an edge from u to v if (u−v) is a perfect square. Using Breadth-First Search (BFS) on this graph, we can efficiently find the minimum number of edges (steps) needed to reach vertex 0 starting from vertex n.
C++
//Driver Code Starts
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
//Driver Code Ends
int minSquares(int n) {
// Creating visited array of size n + 1
vector<bool> vis(n + 1, false);
// Queue of pair to store number and count
// of steps to reach that number from n by
// subtacting a square in each step
queue<pair<int, int>> q;
// Push initial number
q.push({n, 0});
// Mark starting node visited
vis[n] = true;
while (!q.empty()) {
auto p = q.front(); q.pop();
int node = p.first;
int steps = p.second;
if (node == 0)
return steps;
// Loop for all possible path
// from 1 to i*i <= current node
for (int i = 1; i * i <= node; i++) {
int next = node - (i * i);
if (!vis[next]) {
// Mark visited
vis[next] = true;
// Push it it Queue
q.push({next, steps + 1});
}
}
}
return -1;
}
//Driver Code Starts
int main() {
int n = 6;
cout << minSquares(n);
return 0;
}
//Driver Code Ends
C
//Driver Code Starts
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct Pair {
int node;
int steps;
};
struct Queue {
struct Pair* arr;
int front, rear, size, capacity;
};
struct Queue* createQueue(int capacity) {
struct Queue* q = (struct Queue*)malloc(sizeof(struct Queue));
q->capacity = capacity;
q->front = q->rear = q->size = 0;
q->arr = (struct Pair*)malloc(capacity * sizeof(struct Pair));
return q;
}
void enqueue(struct Queue* q, struct Pair val) {
q->arr[q->rear++] = val;
q->size++;
}
struct Pair dequeue(struct Queue* q) {
return q->arr[q->front++];
}
int isEmpty(struct Queue* q) {
return q->size == 0;
}
//Driver Code Ends
int minSquares(int n) {
// Creating visited array of size n + 1
bool* vis = (bool*)calloc(n + 1, sizeof(bool));
// Queue of pair to store number and count
// of steps to reach that number from n by
// subtacting a square in each step
struct Queue* q = createQueue(n * n + 1);
// Push initial number
enqueue(q, (struct Pair){n, 0});
// Mark starting node visited
vis[n] = true;
while (!isEmpty(q)) {
struct Pair p = dequeue(q);
int node = p.node;
int steps = p.steps;
if (node == 0)
return steps;
// Loop for all possible path
// from 1 to i*i <= current node
for (int i = 1; i * i <= node; i++) {
int next = node - (i * i);
if (!vis[next]) {
// Mark visited
vis[next] = true;
// Push it it Queue
enqueue(q, (struct Pair){next, steps + 1});
}
}
}
return -1;
}
//Driver Code Starts
int main() {
int n = 6;
printf("%d", minSquares(n));
return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
import java.util.Queue;
import java.util.LinkedList;
class GFG {
//Driver Code Ends
static int minSquares(int n) {
// Creating visited array of size n + 1
boolean[] vis = new boolean[n + 1];
// Queue of pair to store number and count
// of steps to reach that number from n by
// subtacting a square in each step
Queue<int[]> q = new LinkedList<>();
// Push initial number
q.add(new int[]{n, 0});
// Mark starting node visited
vis[n] = true;
while (!q.isEmpty()) {
int[] p = q.poll();
int node = p[0];
int steps = p[1];
if (node == 0)
return steps;
// Loop for all possible path
// from 1 to i*i <= current node
for (int i = 1; i * i <= node; i++) {
int next = (node - (i * i));
if (!vis[next]) {
// Mark visited
vis[next] = true;
// Push it it Queue
q.add(new int[]{next, steps + 1});
}
}
}
return -1;
}
//Driver Code Starts
public static void main(String[] args) {
int n = 6;
System.out.println(minSquares(n));
}
}
//Driver Code Ends
Python
#Driver Code Starts
from collections import deque
#Driver Code Ends
def minSquares(n):
# Creating visited array of size n + 1
vis = [False] * (n + 1)
# Queue of pair to store number and count
# of steps to reach that number from n by
# subtacting a square in each step
q = deque()
# Push initial number
q.append((n, 0))
# Mark starting node visited
vis[n] = True
while q:
node, steps = q.popleft()
if node == 0:
return steps
# Loop for all possible path
# from 1 to i*i <= current node
i = 1
while i * i <= node:
next_val = node - (i * i)
if not vis[next_val]:
# Mark visited
vis[next_val] = True
# Push it it Queue
q.append((next_val, steps + 1))
i += 1
return -1
#Driver Code Starts
if __name__ == "__main__":
n = 6
print(minSquares(n))
#Driver Code Ends
C#
//Driver Code Starts
using System;
using System.Collections.Generic;
class GFG {
//Driver Code Ends
static int minSquares(int n) {
// Creating visited array of size n + 1
bool[] vis = new bool[n + 1];
// Queue of pair to store number and count
// of steps to reach that number from n by
// subtacting a square in each step
Queue<(int, int)> q = new Queue<(int, int)>();
// Push initial number
q.Enqueue((n, 0));
// Mark starting node visited
vis[n] = true;
while (q.Count > 0) {
var (node, steps) = q.Dequeue();
if (node == 0)
return steps;
// Loop for all possible path
// from 1 to i*i <= current node
for (int i = 1; i * i <= node; i++) {
int next = node - (i * i);
if (!vis[next]) {
// Mark visited
vis[next] = true;
// Push it it Queue
q.Enqueue((next, steps + 1));
}
}
}
return -1;
}
//Driver Code Starts
static void Main() {
int n = 6;
Console.WriteLine(minSquares(n));
}
}
//Driver Code Ends
JavaScript
//Driver Code Starts
const Denque = require('denque');
//Driver Code Ends
function minSquares(n) {
// Creating visited array of size n + 1
const vis = new Array(n + 1).fill(false);
// Queue of pair to store number and count
// of steps to reach that number from n by
// subtracting a square in each step
const q = new Denque();
// Push initial number
q.push([n, 0]);
// Mark starting node visited
vis[n] = true;
while (q.length > 0) {
const [node, steps] = q.shift();
if (node === 0)
return steps;
// Loop for all possible path
// from 1 to i*i <= current node
for (let i = 1; i * i <= node; i++) {
const next = node - i * i;
if (!vis[next]) {
// Mark visited
vis[next] = true;
// Push it in Queue
q.push([next, steps + 1]);
}
}
}
return -1;
}
//Driver Code Starts
// Driver code
const n = 6;
console.log(minSquares(n));
//Driver Code Ends
Time Complexity: O(n*sqrt(n))
Auxiliary Space: O(n), used for queue and visited array.
[Expected Approach] - Using Mathematics(Lagrange's Four Square Theorem)
Lagrange's four-square theorem, also known as Bachet's conjecture, states that every non-negative integer can be represented as a sum of four non-negative integer squares. That is, the squares form an additive basis of order four:
p = a2 + b2 + c2 + d2, where the four numbers a, b, c, d are integers.
Therefore, we can deduce that any positive number can be expressed as sum of at-most 4 square numbers.
Case 1:
If number is a perfect square => minimum number of squares needed = 1
Example : 1, 4, 9, etc.
Case 2:
If the number is the sum of 2 square numbers => minimum number of squares needed = 2
Example : 2, 5, 18, etc.
Case 3:
If the number is not of the form 4k x (8m + 7) such that k, m ∈ W => minimum number of squares needed = 3
Example : 6, 11, 12 etc.
Case 4:
If the number is of the form 4k x (8m + 7) such that k, m ∈ W=> minimum number of squares needed = 4
Example : 7, 15, 23 etc.
C++
//Driver Code Starts
#include <iostream>
#include <cmath>
using namespace std;
//Driver Code Ends
bool isSquare(int x) {
int sqRoot = sqrt(x);
return (sqRoot * sqRoot == x);
}
int minSquares(int n) {
// if n is a perfect square
if (isSquare(n)) {
return 1;
}
// if the number is the
// sum of two perfect squares
for (int i = 1; i * i <= n; i++) {
if (isSquare(n - (i * i))) {
return 2;
}
}
// if n is of the form 4^a (8*b + 7).
while (n > 0 && n % 4 == 0) {
n /= 4;
}
if (n % 8 == 7) {
return 4;
}
// since all the other cases have been evaluated,
// the answer can only then be 3 if the program
// reaches here
return 3;
}
//Driver Code Starts
int main() {
int n = 6;
cout << minSquares(n) << endl;
return 0;
}
//Driver Code Ends
C
//Driver Code Starts
#include <stdio.h>
#include <math.h>
//Driver Code Ends
int isSquare(int x) {
int sqRoot = sqrt(x);
return (sqRoot * sqRoot == x);
}
int minSquares(int n) {
// if n is a perfect square
if (isSquare(n)) {
return 1;
}
// if the number is the
// sum of two perfect squares
for (int i = 1; i * i <= n; i++) {
if (isSquare(n - (i * i))) {
return 2;
}
}
// if n is of the form 4^a (8*b + 7).
while (n > 0 && n % 4 == 0) {
n /= 4;
}
if (n % 8 == 7) {
return 4;
}
// since all the other cases have been evaluated,
// the answer can only then be 3 if the program
// reaches here
return 3;
}
//Driver Code Starts
int main() {
int n = 6;
printf("%d
", minSquares(n));
return 0;
}
//Driver Code Ends
Java
//Driver Code Starts
class GFG {
//Driver Code Ends
static boolean isSquare(int x) {
int sqRoot = (int) Math.sqrt(x);
return (sqRoot * sqRoot == x);
}
static int minSquares(int n) {
// if n is a perfect square
if (isSquare(n)) {
return 1;
}
// if the number is the
// sum of two perfect squares
for (int i = 1; i * i <= n; i++) {
if (isSquare(n - (i * i))) {
return 2;
}
}
// if n is of the form 4^a (8*b + 7).
while (n > 0 && n % 4 == 0) {
n /= 4;
}
if (n % 8 == 7) {
return 4;
}
// since all the other cases have been evaluated,
// the answer can only then be 3 if the program
// reaches here
return 3;
}
//Driver Code Starts
public static void main(String[] args) {
int n = 6;
System.out.println(minSquares(n));
}
}
//Driver Code Ends
Python
#Driver Code Starts
import math
#Driver Code Ends
def isSquare(x):
sqRoot = int(math.sqrt(x))
return (sqRoot * sqRoot == x)
def minSquares(n):
# if n is a perfect square
if isSquare(n):
return 1
# if the number is the
# sum of two perfect squares
for i in range(1, int(math.sqrt(n)) + 1):
if isSquare(n - (i * i)):
return 2
# if n is of the form 4^a (8*b + 7).
while n > 0 and n % 4 == 0:
n //= 4
if n % 8 == 7:
return 4
# since all the other cases have been evaluated,
# the answer can only then be 3 if the program
# reaches here
return 3
#Driver Code Starts
if __name__ == "__main__":
n = 6
print(minSquares(n))
#Driver Code Ends
C#
//Driver Code Starts
using System;
class GFG {
//Driver Code Ends
static bool isSquare(int x) {
int sqRoot = (int)Math.Sqrt(x);
return (sqRoot * sqRoot == x);
}
static int minSquares(int n) {
// if n is a perfect square
if (isSquare(n)) {
return 1;
}
// if the number is the
// sum of two perfect squares
for (int i = 1; i * i <= n; i++) {
if (isSquare(n - (i * i))) {
return 2;
}
}
// if n is of the form 4^a (8*b + 7).
while (n > 0 && n % 4 == 0) {
n /= 4;
}
if (n % 8 == 7) {
return 4;
}
// since all the other cases have been evaluated,
// the answer can only then be 3 if the program
// reaches here
return 3;
}
//Driver Code Starts
static void Main() {
int n = 6;
Console.WriteLine(minSquares(n));
}
}
//Driver Code Ends
JavaScript
function isSquare(x) {
let sqRoot = Math.floor(Math.sqrt(x));
return (sqRoot * sqRoot === x);
}
function minSquares(n) {
// if n is a perfect square
if (isSquare(n)) {
return 1;
}
// if the number is the
// sum of two perfect squares
for (let i = 1; i * i <= n; i++) {
if (isSquare(n - (i * i))) {
return 2;
}
}
// if n is of the form 4^a (8*b + 7).
while (n > 0 && n % 4 === 0) {
n /= 4;
}
if (n % 8 === 7) {
return 4;
}
// since all the other cases have been evaluated,
// the answer can only then be 3 if the program
// reaches here
return 3;
}
// Driver code
//Driver Code Starts
let n = 6;
console.log(minSquares(n));
//Driver Code Ends
Time Complexity: O(sqrt(n)) - to check if n is sum of 2 squared numbers, we run a for loop from 1 to sqrt(n).
Auxiliary Space: O(1)
Explore
DSA Fundamentals
Data Structures
Algorithms
Advanced
Interview Preparation
Practice Problem