Given an integer N, the task is to find the number of ways to represent the number N as sum of perfect squares.
Examples:
Input: N = 9
Output: 4
Explanation:
There are four ways to represent 9 as the sum of perfect squares:
1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 = 9
1 + 1 + 1 + 1 + 1 + 4 = 9
1 + 4 + 4 = 9
9 = 9Input: N = 8
Output: 3
Naive Approach: The idea is to store all the perfect squares less than or equal to N in an array. The problem now reduces to finding the ways to sum to N using array elements with repetition allowed which can be solved using recursion. Follow the steps below to solve the problem:
- Store all the perfect squares less than or equal to N and in an array psquare[].
- Create a recursion function countWays(index, target) that takes two parameters index, (initially N-1) and target (initially N):
- Handle the base cases:
- If the target is 0, return 1.
- If either index or target is less than 0, return 0.
- Otherwise, include the element, psquare[index] in the sum by subtracting it from the target and recursively calling for the remaining value of target.
- Exclude the element, psquare[index] from the sum by moving to the next index and recursively calling for the same value of target.
- Return the sum obtained by including and excluding the element.
- Handle the base cases:
- Print the value of countWays(N-1, N) as the result.
Below is the implementation of the above approach:
C++
// C++ program for the above approach#include <bits/stdc++.h>using namespace std;Â
// Store perfect squares// less than or equal to Nvector<int> psquare;Â
// Utility function to calculate perfect// squares less than or equal to Nvoid calcPsquare(int N){Â Â Â Â for (int i = 1; i * i <= N; i++)Â Â Â Â Â Â Â Â psquare.push_back(i * i);}Â
// Function to find the number// of ways to represent a number// as sum of perfect squaresint countWays(int index, int target){    // Handle the base cases    if (target == 0)        return 1;Â
    if (index < 0 || target < 0)        return 0;Â
    // Include the i-th index element    int inc = countWays(        index, target - psquare[index]);Â
    // Exclude the i-th index element    int exc = countWays(index - 1, target);Â
    // Return the result    return inc + exc;}Â
// Driver Codeint main(){    // Given Input    int N = 9;Â
    // Precalculate perfect    // squares <= N    calcPsquare(N);Â
    // Function Call    cout << countWays(psquare.size() - 1, N);Â
    return 0;} |
Java
// Java program for the above approachimport java.io.*;import java.lang.*;import java.util.*;Â
public class GFG {Â
    // Store perfect squares    // less than or equal to N    static ArrayList<Integer> psquare = new ArrayList<>();Â
    // Utility function to calculate perfect    // squares less than or equal to N    static void calcPsquare(int N)    {        for (int i = 1; i * i <= N; i++)            psquare.add(i * i);    }Â
    // Function to find the number    // of ways to represent a number    // as sum of perfect squares    static int countWays(int index, int target)    {        // Handle the base cases        if (target == 0)            return 1;Â
        if (index < 0 || target < 0)            return 0;Â
        // Include the i-th index element        int inc            = countWays(index, target - psquare.get(index));Â
        // Exclude the i-th index element        int exc = countWays(index - 1, target);Â
        // Return the result        return inc + exc;    }Â
    // Driver Code    public static void main(String[] args)    {        // Given Input        int N = 9;Â
        // Precalculate perfect        // squares <= N        calcPsquare(N);Â
        // Function Call        System.out.print(countWays(psquare.size() - 1, N));    }}Â
// This code is contributed by Kingash. |
Python3
# Python3 program for the above approachÂ
# Store perfect squares# less than or equal to Npsquare = []Â
# Utility function to calculate perfect# squares less than or equal to Ndef calcPsquare(N):         for i in range(1, N):        if i * i > N:            break                 psquare.append(i * i)Â
# Function to find the number# of ways to represent a number# as sum of perfect squaresdef countWays(index, target):         # Handle the base cases    if (target == 0):        return 1Â
    if (index < 0 or target < 0):        return 0Â
    # Include the i-th index element    inc = countWays(index, target - psquare[index])Â
    # Exclude the i-th index element    exc = countWays(index - 1, target)Â
    # Return the result    return inc + excÂ
# Driver Codeif __name__ == '__main__':         # Given Input    N = 9Â
    # Precalculate perfect    # squares <= N    calcPsquare(N)Â
    # Function Call    print (countWays(len(psquare) - 1, N))Â
# This code is contributed by mohit kumar 29 |
C#
using System.IO;using System;using System.Collections;Â
class GFG {    // Store perfect squares    // less than or equal to N    static ArrayList psquare = new ArrayList();Â
    // Utility function to calculate perfect    // squares less than or equal to N    static void calcPsquare(int N)    {        for (int i = 1; i * i <= N; i++)            psquare.Add(i * i);    }Â
    // Function to find the number    // of ways to represent a number    // as sum of perfect squares    static int countWays(int index, int target)    {        // Handle the base cases        if (target == 0)            return 1;Â
        if (index < 0 || target < 0)            return 0;Â
        // Include the i-th index element        int inc = countWays(index,                            target - (int)psquare[index]);Â
        // Exclude the i-th index element        int exc = countWays(index - 1, target);Â
        // Return the result        return inc + exc;    }Â
    static void Main()    {               // Given Input        int N = 9;Â
        // Precalculate perfect        // squares <= N        calcPsquare(N);Â
        // Function Call        Console.WriteLine(countWays(psquare.Count - 1, N));    }}Â
// This code is contributed by abhinavjain194. |
Javascript
<script>Â
// JavaScript program for the above approachÂ
// Store perfect squares// less than or equal to Nvar psquare = []Â
// Utility function to calculate perfect// squares less than or equal to Nfunction calcPsquare(N){Â Â Â Â var i;Â Â Â Â for (i = 1; i * i <= N; i++)Â Â Â Â Â Â Â Â psquare.push(i * i);}Â
// Function to find the number// of ways to represent a number// as sum of perfect squaresfunction countWays(index, target){    // Handle the base cases    if (target == 0)        return 1;Â
    if (index < 0 || target < 0)        return 0;Â
    // Include the i-th index element    var inc = countWays(        index, target - psquare[index]);Â
    // Exclude the i-th index element    var exc = countWays(index - 1, target);Â
    // Return the result    return inc + exc;}Â
// Driver Code    // Given Input    var N = 9;Â
    // Precalculate perfect    // squares <= N    calcPsquare(N);Â
    // Function Call    document.write(countWays(psquare.length - 1, N));Â
</script> |
4
Â
Time Complexity: O(2K), where K is the number of perfect squares less than or equal to N
Auxiliary Space: O(1)
Efficient approach: This problem has overlapping subproblems and optimal substructure property. To optimize the above approach, the idea is to use dynamic programming by memoizing the above recursive calls using a 2D array of size K*N, where K is the number of perfect squares less than or equal to N.
Below is the implementation of the above approach:Â
C++
// C++ program for the above approach#include <bits/stdc++.h>using namespace std;Â
// Store perfect squares// less than or equal to Nvector<int> psquare;Â
// Utility function to calculate// perfect squares <= Nvoid calcPsquare(int N){Â Â Â Â for (int i = 1; i * i <= N; i++)Â Â Â Â Â Â Â Â psquare.push_back(i * i);}Â
// DP array for memoizationvector<vector<int> > dp;Â
// Recursive function to count// number of ways to represent// a number as a sum of perfect squaresint countWaysUtil(int index, int target){    // Handle base cases    if (target == 0)        return 1;    if (index < 0 || target < 0)        return 0;Â
    // If already computed, return the result    if (dp[index][target] != -1)        return dp[index][target];Â
    // Else, compute the result    return dp[index][target]           = countWaysUtil(                 index, target - psquare[index])Â
             + countWaysUtil(                   index - 1, target);}Â
// Function to find the number of ways to// represent a number as a sum of perfect squaresint countWays(int N){    // Precalculate perfect squares less    // than or equal to N    calcPsquare(N);Â
    // Create dp array to memoize    dp.resize(psquare.size() + 1,              vector<int>(N + 1, -1));Â
    // Function call to fill dp array    return countWaysUtil(psquare.size() - 1, N);}Â
// Driver Codeint main(){    // Given Input    int N = 9;Â
    // Function Call    cout << countWays(N);Â
    return 0;} |
Java
// Java program for the above approachimport java.io.*;import java.lang.*;import java.util.*;Â
public class GFG {         // Store perfect squares    // less than or equal to N    private static ArrayList<Integer> psquare;Â
         // Utility function to calculate    // perfect squares <= N    private static void calcPsquare(int n) {Â
        for (int i = 1; i * i <= n; i++)            psquare.add(i * i);             }         // DP array for memoization    private static int[][] dp;         // Recursive function to count    // number of ways to represent    // a number as a sum of perfect squares    private static int countWaysUtil(int index, int target) {        // Handle base cases        if (target == 0)            return 1;        if (index < 0 || target < 0)            return 0;              // If already computed, return the result        if (dp[index][target] != -1)            return dp[index][target];              // Else, compute the result        return dp[index][target]               = countWaysUtil(                     index, target - psquare.get(index))                       + countWaysUtil(                       index - 1, target);    }         // Function to find the number of ways to    // represent a number as a sum of perfect squares    private static int countWays(int n) {        // Precalculate perfect squares less        // than or equal to N        psquare = new ArrayList<Integer>();        calcPsquare(n);              // Create dp array to memoize        dp = new int[psquare.size()+1][n+1];        for(int i = 0; i<=psquare.size(); i++)Arrays.fill(dp[i], -1);              // Function call to fill dp array        return countWaysUtil(psquare.size() - 1, n);    }Â
Â
Â
    // Driver Code    public static void main(String[] args)    {        // Given Input        int N = 9;Â
        // Function Call        System.out.print(countWays(N));    }     }Â
// This code is contributed by Dheeraj Bhagchandani. |
Python3
# Python3 program for the above approachfrom math import sqrtÂ
# Store perfect squares# less than or equal to Npsquare = []Â
# DP array for memoizationdp = []Â
# Utility function to calculate# perfect squares <= Ndef calcPsquare(N):         global psquare    for i in range(1, int(sqrt(N)) + 1, 1):        psquare.append(i * i)Â
# Recursive function to count# number of ways to represent# a number as a sum of perfect squaresdef countWaysUtil(index, target):         global dp         # Handle base cases    if (target == 0):        return 1    if (index < 0 or target < 0):        return 0Â
    # If already computed, return the result    if (dp[index][target] != -1):        return dp[index][target]Â
    dp[index][target] = (countWaysUtil(                               index, target - psquare[index]) +                         countWaysUtil(index - 1, target))Â
    # Else, compute the result    return dp[index][target]Â
# Function to find the number of ways to# represent a number as a sum of perfect squaresdef countWays(N):         global dp    global psquare         # Precalculate perfect squares less    # than or equal to N    calcPsquare(N)    temp = [-1 for i in range(N + 1)]         # Create dp array to memoize    dp = [temp for i in range(len(psquare) + 1)]Â
    # Function call to fill dp array    return countWaysUtil(len(psquare) - 1, N) - 1Â
# Driver Codeif __name__ == '__main__':         # Given Input    N = 9         # Function Call    print(countWays(N))Â
# This code is contributed by ipg2016107 |
C#
// C# program for the above approachusing System;using System.Collections.Generic;Â
class GFG{Â Â Â Â Â // Store perfect squares// less than or equal to Nstatic List<int> psquare;Â
// Utility function to calculate// perfect squares <= Nprivate static void calcPsquare(int n) {Â Â Â Â for(int i = 1; i * i <= n; i++)Â Â Â Â Â Â Â Â psquare.Add(i * i);}Â
// DP array for memoizationprivate static int[,]dp;Â
// Recursive function to count// number of ways to represent// a number as a sum of perfect squaresprivate static int countWaysUtil(int index,                                 int target) {         // Handle base cases    if (target == 0)        return 1;    if (index < 0 || target < 0)        return 0;      // If already computed, return the result    if (dp[index, target] != -1)        return dp[index, target];      // Else, compute the result    return dp[index, target] = countWaysUtil(index,                                              target - psquare[index]) +                                countWaysUtil(index - 1, target);}Â
// Function to find the number of ways to// represent a number as a sum of perfect squaresprivate static int countWays(int n){         // Precalculate perfect squares less    // than or equal to N    psquare = new List<int>();    calcPsquare(n);      // Create dp array to memoize    dp = new int[psquare.Count + 1, n + 1];    for(int i = 0; i <= psquare.Count; i++)    {        for(int j = 0; j <= n; j++)        {            dp[i, j] = -1;        }                 //Array.Fill(dp[i], -1);    }      // Function call to fill dp array    return countWaysUtil(psquare.Count - 1, n);}Â
// Driver Codestatic void Main() {         // Given Input    int N = 9;Â
    // Function Call   Console.Write(countWays(N));}}Â
// This code is contributed by SoumikMondal |
Javascript
<script>Â
// JavaScript program for the above approachÂ
let psquare;Â
function calcPsquare(n){Â Â Â Â Â for (let i = 1; i * i <= n; i++)Â Â Â Â Â Â Â Â Â Â Â Â psquare.push(i * i);}Â
 // DP array for memoizationlet dp;Â
// Recursive function to count    // number of ways to represent    // a number as a sum of perfect squaresfunction countWaysUtil(index,target){    // Handle base cases        if (target == 0)            return 1;        if (index < 0 || target < 0)            return 0;               // If already computed, return the result        if (dp[index][target] != -1)            return dp[index][target];               // Else, compute the result        return dp[index][target]               = countWaysUtil(                     index, target - psquare[index])                        + countWaysUtil(                       index - 1, target);}Â
// Function to find the number of ways to    // represent a number as a sum of perfect squaresfunction countWays(n){    // Precalculate perfect squares less        // than or equal to N        psquare = [];        calcPsquare(n);               // Create dp array to memoize        dp = new Array(psquare.length+1);        for(let i=0;i<psquare.length+1;i++)        {            dp[i]=new Array(n+1);            for(let j=0;j<n+1;j++)            {                dp[i][j]=-1;            }        }                        // Function call to fill dp array        return countWaysUtil(psquare.length - 1, n);}Â
// Driver Code// Given Inputlet N = 9;Â
// Function Calldocument.write(countWays(N));Â
Â
// This code is contributed by patel2127Â
</script> |
4
Time Complexity: O(K*N), where K is the number of perfect squares less than or equal to N
Auxiliary Space: O(K*N)
Â
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!
