Count ways to represent a number as sum of perfect squares - GeeksforGeeks

06 Jul, 2021
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 = 9Output: 4Explanation:There are four ways to represent 9 as the sum of perfect squares:1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 = 91 + 1 + 1 + 1 + 1 + 4 = 91 + 4 + 4 = 99 = 9
Input: N = 8Output: 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:If the target is 0, return 1.If either index or target is less than 0, return 0.
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.
Print the value of countWays(N-1, N) as the result.
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// 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 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 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
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.
<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 NAuxiliary 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++
Java
Python3
C#
Javascript
// 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 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 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# 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
<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 NAuxiliary Space: O(K*N)
 
Kingash
abhinavjain194
mohit kumar 29
SURENDRA_GANGWAR
dheeraj0105
ipg2016107
SoumikMondal
patel2127
maths-perfect-square
Mathematical
Recursion
Searching
Searching
Mathematical
Recursion
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Comments
Old Comments
Find all factors of a natural number | Set 1
Check if a number is Palindrome
Program to print prime numbers from 1 to N.
Fizz Buzz Implementation
Program to multiply two matrices
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Recursion
Program for Tower of Hanoi
Program for Sum of the digits of a given number
Backtracking | Introduction