Count ways to represent a number as sum of perfect squares
Last Updated :
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 = 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 = 9
Input: 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.
- Print the value of countWays(N-1, N) as the result.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
vector< int > psquare;
void calcPsquare( int N)
{
for ( int i = 1; i * i <= N; i++)
psquare.push_back(i * i);
}
int countWays( int index, int target)
{
if (target == 0)
return 1;
if (index < 0 || target < 0)
return 0;
int inc = countWays(
index, target - psquare[index]);
int exc = countWays(index - 1, target);
return inc + exc;
}
int main()
{
int N = 9;
calcPsquare(N);
cout << countWays(psquare.size() - 1, N);
return 0;
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
public class GFG {
static ArrayList<Integer> psquare = new ArrayList<>();
static void calcPsquare( int N)
{
for ( int i = 1 ; i * i <= N; i++)
psquare.add(i * i);
}
static int countWays( int index, int target)
{
if (target == 0 )
return 1 ;
if (index < 0 || target < 0 )
return 0 ;
int inc
= countWays(index, target - psquare.get(index));
int exc = countWays(index - 1 , target);
return inc + exc;
}
public static void main(String[] args)
{
int N = 9 ;
calcPsquare(N);
System.out.print(countWays(psquare.size() - 1 , N));
}
}
|
Python3
psquare = []
def calcPsquare(N):
for i in range ( 1 , N):
if i * i > N:
break
psquare.append(i * i)
def countWays(index, target):
if (target = = 0 ):
return 1
if (index < 0 or target < 0 ):
return 0
inc = countWays(index, target - psquare[index])
exc = countWays(index - 1 , target)
return inc + exc
if __name__ = = '__main__' :
N = 9
calcPsquare(N)
print (countWays( len (psquare) - 1 , N))
|
C#
using System.IO;
using System;
using System.Collections;
class GFG {
static ArrayList psquare = new ArrayList();
static void calcPsquare( int N)
{
for ( int i = 1; i * i <= N; i++)
psquare.Add(i * i);
}
static int countWays( int index, int target)
{
if (target == 0)
return 1;
if (index < 0 || target < 0)
return 0;
int inc = countWays(index,
target - ( int )psquare[index]);
int exc = countWays(index - 1, target);
return inc + exc;
}
static void Main()
{
int N = 9;
calcPsquare(N);
Console.WriteLine(countWays(psquare.Count - 1, N));
}
}
|
Javascript
<script>
var psquare = []
function calcPsquare(N)
{
var i;
for (i = 1; i * i <= N; i++)
psquare.push(i * i);
}
function countWays(index, target)
{
if (target == 0)
return 1;
if (index < 0 || target < 0)
return 0;
var inc = countWays(
index, target - psquare[index]);
var exc = countWays(index - 1, target);
return inc + exc;
}
var N = 9;
calcPsquare(N);
document.write(countWays(psquare.length - 1, N));
</script>
|
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++
#include <bits/stdc++.h>
using namespace std;
vector< int > psquare;
void calcPsquare( int N)
{
for ( int i = 1; i * i <= N; i++)
psquare.push_back(i * i);
}
vector<vector< int > > dp;
int countWaysUtil( int index, int target)
{
if (target == 0)
return 1;
if (index < 0 || target < 0)
return 0;
if (dp[index][target] != -1)
return dp[index][target];
return dp[index][target]
= countWaysUtil(
index, target - psquare[index])
+ countWaysUtil(
index - 1, target);
}
int countWays( int N)
{
calcPsquare(N);
dp.resize(psquare.size() + 1,
vector< int >(N + 1, -1));
return countWaysUtil(psquare.size() - 1, N);
}
int main()
{
int N = 9;
cout << countWays(N);
return 0;
}
|
Java
import java.io.*;
import java.lang.*;
import java.util.*;
public class GFG {
private static ArrayList<Integer> psquare;
private static void calcPsquare( int n) {
for ( int i = 1 ; i * i <= n; i++)
psquare.add(i * i);
}
private static int [][] dp;
private static int countWaysUtil( int index, int target) {
if (target == 0 )
return 1 ;
if (index < 0 || target < 0 )
return 0 ;
if (dp[index][target] != - 1 )
return dp[index][target];
return dp[index][target]
= countWaysUtil(
index, target - psquare.get(index))
+ countWaysUtil(
index - 1 , target);
}
private static int countWays( int n) {
psquare = new ArrayList<Integer>();
calcPsquare(n);
dp = new int [psquare.size()+ 1 ][n+ 1 ];
for ( int i = 0 ; i<=psquare.size(); i++)Arrays.fill(dp[i], - 1 );
return countWaysUtil(psquare.size() - 1 , n);
}
public static void main(String[] args)
{
int N = 9 ;
System.out.print(countWays(N));
}
}
|
Python3
from math import sqrt
psquare = []
dp = []
def calcPsquare(N):
global psquare
for i in range ( 1 , int (sqrt(N)) + 1 , 1 ):
psquare.append(i * i)
def countWaysUtil(index, target):
global dp
if (target = = 0 ):
return 1
if (index < 0 or target < 0 ):
return 0
if (dp[index][target] ! = - 1 ):
return dp[index][target]
dp[index][target] = (countWaysUtil(
index, target - psquare[index]) +
countWaysUtil(index - 1 , target))
return dp[index][target]
def countWays(N):
global dp
global psquare
calcPsquare(N)
temp = [ - 1 for i in range (N + 1 )]
dp = [temp for i in range ( len (psquare) + 1 )]
return countWaysUtil( len (psquare) - 1 , N) - 1
if __name__ = = '__main__' :
N = 9
print (countWays(N))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static List< int > psquare;
private static void calcPsquare( int n)
{
for ( int i = 1; i * i <= n; i++)
psquare.Add(i * i);
}
private static int [,]dp;
private static int countWaysUtil( int index,
int target)
{
if (target == 0)
return 1;
if (index < 0 || target < 0)
return 0;
if (dp[index, target] != -1)
return dp[index, target];
return dp[index, target] = countWaysUtil(index,
target - psquare[index]) +
countWaysUtil(index - 1, target);
}
private static int countWays( int n)
{
psquare = new List< int >();
calcPsquare(n);
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;
}
}
return countWaysUtil(psquare.Count - 1, n);
}
static void Main()
{
int N = 9;
Console.Write(countWays(N));
}
}
|
Javascript
<script>
let psquare;
function calcPsquare(n)
{
for (let i = 1; i * i <= n; i++)
psquare.push(i * i);
}
let dp;
function countWaysUtil(index,target)
{
if (target == 0)
return 1;
if (index < 0 || target < 0)
return 0;
if (dp[index][target] != -1)
return dp[index][target];
return dp[index][target]
= countWaysUtil(
index, target - psquare[index])
+ countWaysUtil(
index - 1, target);
}
function countWays(n)
{
psquare = [];
calcPsquare(n);
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;
}
}
return countWaysUtil(psquare.length - 1, n);
}
let N = 9;
document.write(countWays(N));
</script>
|
Time Complexity: O(K*N), where K is the number of perfect squares less than or equal to N
Auxiliary Space: O(K*N)
Like Article
Suggest improvement
Share your thoughts in the comments
Please Login to comment...