Minimum Perfect Squares that sums to N (original) (raw)

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.

Table of Content

[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 #include 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 #include using namespace std; //Driver Code Ends

int minSquaresRec(int n, vector& 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 #include 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.

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 #include #include 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 #include 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)