A child is running up a staircase with n steps and can hop either 1 step, 2 steps, or 3 steps at a time. Implement a method to count how many possible ways the child can run up the stairs.
Examples:
Input : 4
Output : 7
Explanation:
Below are the seven ways
1 step + 1 step + 1 step + 1 step
1 step + 2 step + 1 step
2 step + 1 step + 1 step
1 step + 1 step + 2 step
2 step + 2 step
3 step + 1 step
1 step + 3 step
Input : 3
Output : 4
Explanation:
Below are the four ways
1 step + 1 step + 1 step
1 step + 2 step
2 step + 1 step
3 step
There are two methods to solve this problem:
- Recursive Method
- Dynamic Programming
Method 1: Recursive.
There are n stairs, and a person is allowed to jump next stair, skip one stair or skip two stairs. So there are n stairs. So if a person is standing at i-th stair, the person can move to i+1, i+2, i+3-th stair. A recursive function can be formed where at current index i the function is recursively called for i+1, i+2 and i+3 th stair.
There is another way of forming the recursive function. To reach a stair i, a person has to jump either from i-1, i-2 or i-3 th stair or i is the starting stair.
Algorithm:
- Create a recursive function (count(int n)) which takes only one parameter.
- Check the base cases. If the value of n is less than 0 then return 0, and if the value of n is equal to zero then return 1 as it is the starting stair.
- Call the function recursively with values n-1, n-2 and n-3 and sum up the values that are returned, i.e. sum = count(n-1) + count(n-2) + count(n-3)
- Return the value of the sum.
C++
#include <iostream>
using namespace std;
class GFG {
public :
int findStep( int n)
{
if (n == 0)
return 1;
else if (n < 0)
return 0;
else
return findStep(n - 3) + findStep(n - 2)
+ findStep(n - 1);
}
};
int main()
{
GFG g;
int n = 4;
cout << g.findStep(n);
return 0;
}
|
C
#include <stdio.h>
int findStep( int n)
{
if (n == 0)
return 1;
else if (n < 0)
return 0;
else
return findStep(n - 3) + findStep(n - 2)
+ findStep(n - 1);
}
int main()
{
int n = 4;
printf ( "%d\n" , findStep(n));
return 0;
}
|
Java
import java.lang.*;
import java.util.*;
public class GfG {
public static int findStep( int n)
{
if ( n == 0 )
return 1 ;
else if (n < 0 )
return 0 ;
else
return findStep(n - 3 ) + findStep(n - 2 )
+ findStep(n - 1 );
}
public static void main(String argc[])
{
int n = 4 ;
System.out.println(findStep(n));
}
}
|
Python
def findStep(n):
if ( n = = 0 ):
return 1
elif (n < 0 ):
return 0
else :
return findStep(n - 3 ) + findStep(n - 2 ) + findStep(n - 1 )
n = 4
print (findStep(n))
|
C#
using System;
public class GfG {
public static int findStep( int n)
{
if ( n == 0)
return 1;
else if (n < 0)
return 0;
else
return findStep(n - 3) + findStep(n - 2)
+ findStep(n - 1);
}
public static void Main()
{
int n = 4;
Console.WriteLine(findStep(n));
}
}
|
Javascript
<script>
function findStep(n)
{
if (n == 0)
return 1;
else if (n < 0)
return 0;
else
return findStep(n - 3) + findStep(n - 2)
+ findStep(n - 1);
}
let n = 4;
document.write(findStep(n));
</script>
|
PHP
<?php
function findStep( $n )
{
if ( $n == 0)
return 1;
else if ( $n < 0)
return 0;
else
return findStep( $n - 3) +
findStep( $n - 2) +
findStep( $n - 1);
}
$n = 4;
echo findStep( $n );
?>
|
Working:

Complexity Analysis:
- Time Complexity: O(3n).
The time complexity of the above solution is exponential, a close upper bound will be O(3n). From each state, 3 recursive function are called. So the upperbound for n states is O(3n).
- Space Complexity: O(N).
Auxillary Space required by the recursive call stack is O(depth of recursion tree).
Note: The Time Complexity of the program can be optimized using Dynamic Programming.
Method 2: Dynamic Programming.
The idea is similar, but it can be observed that there are n states but the recursive function is called 3 ^ n times. That means that some states are called repeatedly. So the idea is to store the value of states. This can be done in two ways.
- Top-Down Approach: The first way is to keep the recursive structure intact and just store the value in a HashMap and whenever the function is called again return the value store without computing ().
- Bottom-Up Approach: The second way is to take an extra space of size n and start computing values of states from 1, 2 .. to n, i.e. compute values of i, i+1, i+2 and then use them to calculate the value of i+3.
Algorithm:
- Create an array of size n + 1 and initialize the first 3 variables with 1, 1, 2. The base cases.
- Run a loop from 3 to n.
- For each index i, computer value of ith position as dp[i] = dp[i-1] + dp[i-2] + dp[i-3].
- Print the value of dp[n], as the Count of the number of ways to reach n th step.
C++
#include <iostream>
using namespace std;
int countWays( int n)
{
int res[n + 1];
res[0] = 1;
res[1] = 1;
res[2] = 2;
for ( int i = 3; i <= n; i++)
res[i] = res[i - 1] + res[i - 2] + res[i - 3];
return res[n];
}
int main()
{
int n = 4;
cout << countWays(n);
return 0;
}
|
C
#include <stdio.h>
int countWays( int n)
{
int res[n + 1];
res[0] = 1;
res[1] = 1;
res[2] = 2;
for ( int i = 3; i <= n; i++)
res[i] = res[i - 1] + res[i - 2] + res[i - 3];
return res[n];
}
int main()
{
int n = 4;
printf ( "%d" , countWays(n));
return 0;
}
|
Java
import java.lang.*;
import java.util.*;
public class GfG {
public static int countWays( int n)
{
int [] res = new int [n + 1 ];
res[ 0 ] = 1 ;
res[ 1 ] = 1 ;
res[ 2 ] = 2 ;
for ( int i = 3 ; i <= n; i++)
res[i] = res[i - 1 ] + res[i - 2 ] + res[i - 3 ];
return res[n];
}
public static void main(String argc[])
{
int n = 4 ;
System.out.println(countWays(n));
}
}
|
Python
def countWays(n):
res = [ 0 ] * (n + 2 )
res[ 0 ] = 1
res[ 1 ] = 1
res[ 2 ] = 2
for i in range ( 3 , n + 1 ):
res[i] = res[i - 1 ] + res[i - 2 ] + res[i - 3 ]
return res[n]
n = 4
print (countWays(n))
|
C#
using System;
public class GfG {
public static int countWays( int n)
{
int [] res = new int [n + 2];
res[0] = 1;
res[1] = 1;
res[2] = 2;
for ( int i = 3; i <= n; i++)
res[i] = res[i - 1] + res[i - 2] + res[i - 3];
return res[n];
}
public static void Main()
{
int n = 4;
Console.WriteLine(countWays(n));
}
}
|
Javascript
<script>
function countWays(n)
{
let res = new Array(n + 2);
res[0] = 1;
res[1] = 1;
res[2] = 2;
for (let i = 3; i <= n; i++)
res[i] = res[i - 1] + res[i - 2] + res[i - 3];
return res[n];
}
let n = 4;
document.write(countWays(n));
</script>
|
PHP
<?php
function countWays( $n )
{
$res [0] = 1;
$res [1] = 1;
$res [2] = 2;
for ( $i = 3; $i <= $n ; $i ++)
$res [ $i ] = $res [ $i - 1] +
$res [ $i - 2] +
$res [ $i - 3];
return $res [ $n ];
}
$n = 4;
echo countWays( $n );
?>
|
1 -> 1 -> 1 -> 1
1 -> 1 -> 2
1 -> 2 -> 1
1 -> 3
2 -> 1 -> 1
2 -> 2
3 -> 1
So Total ways: 7
- Complexity Analysis:
- Time Complexity: O(n).
Only one traversal of the array is needed. So Time Complexity is O(n).
- Space Complexity: O(n).
To store the values in a DP, n extra space is needed.
Method 3: Matrix Exponentiation (O(logn) Approach)
Matrix Exponentiation is mathematical ways to solve DP problem in better time complexity. Matrix Exponentiation Technique has Transformation matrix of Size K X K and Functional Vector (K X 1) .By taking n-1th power of Transformation matrix and Multiplying It With functional vector Give Resultant Vector say it Res of Size K X 1. First Element of Res will be Answer for given n value. This Approach Will Take O(K^3logn) Time Complexity Which Is Complexity of Finding (n-1) power of Transformation Matrix.
Key Terms:
K = No of Terms in which F(n) depend ,from Recurrence Relation We can Say That F(n) depend On F(n-1) and F(n-2). => K =3
F1 = Vector (1D array) that contain F(n) value of First K terms. Since K=3 =>F1 will have F(n) value of first 2 terms. F1=[1,2,4]
T = Transformation Matrix that is a 2D matrix of Size K X K and Consist Of All 1 After Diagonal And Rest All Zero except last row. Last Row Will have coefficient Of all K terms in which F(n) depends In Reverse Order. => T =[ [0 1 0] ,[0 0 1], [1 1 1] ].
Algorithms:
1)Take Input N
2)If N < K then Return Precalculated Answer //Base Condition
3)construct F1 Vector and T (Transformation Matrix)
4)Take N-1th power of T by using Optimal Power(T,N) Methods and assign it in T
5)return (TXF)[1]
for Optimal Power(T, N) Methods Refer Following Article: https://www.geeksforgeeks.org/write-a-c-program-to-calculate-powxn/
C++
#include <bits/stdc++.h>
#define k 3
using namespace std;
vector<vector< int > > multiply(vector<vector< int > > A,
vector<vector< int > > B)
{
vector<vector< int > > C(k + 1, vector< int >(k + 1));
for ( int i = 1; i <= k; i++) {
for ( int j = 1; j <= k; j++) {
for ( int x = 1; x <= k; x++) {
C[i][j] = (C[i][j] + (A[i][x] * B[x][j]));
}
}
}
return C;
}
vector<vector< int > > pow (vector<vector< int > > t, int n)
{
if (n == 1) {
return t;
}
if (n & 1) {
return multiply(t, pow (t, n - 1));
}
else {
vector<vector< int > > X = pow (t, n / 2);
return multiply(X, X);
}
}
int compute( int n)
{
if (n == 0)
return 1;
if (n == 1)
return 1;
if (n == 2)
return 2;
int f1[k + 1] = {};
f1[1] = 1;
f1[2] = 2;
f1[3] = 4;
vector<vector< int > > t(k + 1, vector< int >(k + 1));
for ( int i = 1; i <= k; i++) {
for ( int j = 1; j <= k; j++) {
if (i < k) {
if (j == i + 1) {
t[i][j] = 1;
}
else {
t[i][j] = 0;
}
continue ;
}
t[i][j] = 1;
}
}
t = pow (t, n - 1);
int sum = 0;
for ( int i = 1; i <= k; i++) {
sum += t[1][i] * f1[i];
}
return sum;
}
int main()
{
int n = 4;
cout << compute(n) << endl;
n = 5;
cout << compute(n) << endl;
n = 10;
cout << compute(n) << endl;
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG {
static int k = 3 ;
static int [][] multiply( int [][] A, int [][] B)
{
int [][] C = new int [k + 1 ][k + 1 ];
for ( int i = 1 ; i <= k; i++) {
for ( int j = 1 ; j <= k; j++) {
for ( int x = 1 ; x <= k; x++) {
C[i][j]
= (C[i][j] + (A[i][x] * B[x][j]));
}
}
}
return C;
}
static int [][] pow( int [][] t, int n)
{
if (n == 1 ) {
return t;
}
if ((n & 1 ) != 0 ) {
return multiply(t, pow(t, n - 1 ));
}
else {
int [][] X = pow(t, n / 2 );
return multiply(X, X);
}
}
static int compute( int n)
{
if (n == 0 )
return 1 ;
if (n == 1 )
return 1 ;
if (n == 2 )
return 2 ;
int f1[] = new int [k + 1 ];
f1[ 1 ] = 1 ;
f1[ 2 ] = 2 ;
f1[ 3 ] = 4 ;
int [][] t = new int [k + 1 ][k + 1 ];
for ( int i = 1 ; i <= k; i++) {
for ( int j = 1 ; j <= k; j++) {
if (i < k) {
if (j == i + 1 ) {
t[i][j] = 1 ;
}
else {
t[i][j] = 0 ;
}
continue ;
}
t[i][j] = 1 ;
}
}
t = pow(t, n - 1 );
int sum = 0 ;
for ( int i = 1 ; i <= k; i++) {
sum += t[ 1 ][i] * f1[i];
}
return sum;
}
public static void main(String[] args)
{
int n = 4 ;
System.out.println(compute(n));
n = 5 ;
System.out.println(compute(n));
n = 10 ;
System.out.println(compute(n));
}
}
|
Python3
k = 3
def multiply(A, B):
C = [[ 0 for x in range (k + 1 )] for y in range (k + 1 )]
for i in range ( 1 , k + 1 ):
for j in range ( 1 , k + 1 ):
for x in range ( 1 , k + 1 ):
C[i][j] = (C[i][j] + (A[i][x] * B[x][j]))
return C
def pow (t, n):
if (n = = 1 ):
return t
if (n & 1 ):
return multiply(t, pow (t, n - 1 ))
else :
X = pow (t, n / / 2 )
return multiply(X, X)
def compute(n):
if (n = = 0 ):
return 1
if (n = = 1 ):
return 1
if (n = = 2 ):
return 2
f1 = [ 0 ] * (k + 1 )
f1[ 1 ] = 1
f1[ 2 ] = 2
f1[ 3 ] = 4
t = [[ 0 for x in range (k + 1 )] for y in range (k + 1 )]
for i in range ( 1 , k + 1 ):
for j in range ( 1 , k + 1 ):
if (i < k):
if (j = = i + 1 ):
t[i][j] = 1
else :
t[i][j] = 0
continue
t[i][j] = 1
t = pow (t, n - 1 )
sum = 0
for i in range ( 1 , k + 1 ):
sum + = t[ 1 ][i] * f1[i]
return sum
n = 4
print (compute(n))
n = 5
print (compute(n))
n = 10
print (compute(n))
|
C#
using System;
class GFG {
static int k = 3;
static int [, ] multiply( int [, ] A, int [, ] B)
{
int [, ] C = new int [k + 1, k + 1];
for ( int i = 1; i <= k; i++) {
for ( int j = 1; j <= k; j++) {
for ( int x = 1; x <= k; x++) {
C[i, j]
= (C[i, j] + (A[i, x] * B[x, j]));
}
}
}
return C;
}
static int [, ] pow( int [, ] t, int n)
{
if (n == 1) {
return t;
}
if ((n & 1) != 0) {
return multiply(t, pow(t, n - 1));
}
else {
int [, ] X = pow(t, n / 2);
return multiply(X, X);
}
}
static int compute( int n)
{
if (n == 0)
return 1;
if (n == 1)
return 1;
if (n == 2)
return 2;
int [] f1 = new int [k + 1];
f1[1] = 1;
f1[2] = 2;
f1[3] = 4;
int [, ] t = new int [k + 1, k + 1];
for ( int i = 1; i <= k; i++) {
for ( int j = 1; j <= k; j++) {
if (i < k) {
if (j == i + 1) {
t[i, j] = 1;
}
else {
t[i, j] = 0;
}
continue ;
}
t[i, j] = 1;
}
}
t = pow(t, n - 1);
int sum = 0;
for ( int i = 1; i <= k; i++) {
sum += t[1, i] * f1[i];
}
return sum;
}
static public void Main()
{
int n = 4;
Console.WriteLine(compute(n));
n = 5;
Console.WriteLine(compute(n));
n = 10;
Console.WriteLine(compute(n));
}
}
|
Javascript
<script>
let k = 3;
function multiply(A,B)
{
let C = new Array(k + 1);
for (let i=0;i<k+1;i++)
{
C[i]= new Array(k+1);
for (let j=0;j<k+1;j++)
{
C[i][j]=0;
}
}
for (let i = 1; i <= k; i++)
{
for (let j = 1; j <= k; j++)
{
for (let x = 1; x <= k; x++)
{
C[i][j] = (C[i][j] + (A[i][x] * B[x][j]));
}
}
}
return C;
}
function pow(t,n)
{
if (n == 1)
{
return t;
}
if ((n & 1) != 0)
{
return multiply(t, pow(t, n - 1));
}
else
{
let X = pow(t, n / 2);
return multiply(X, X);
}
}
function compute(n)
{
if (n == 0) return 1;
if (n == 1) return 1;
if (n == 2) return 2;
let f1= new Array(k + 1);
f1[1] = 1;
f1[2] = 2;
f1[3] = 4;
let t = new Array(k + 1);
for (let i=0;i<k+1;i++)
{
t[i]= new Array(k+1);
for (let j=0;j<k+1;j++)
{
t[i][j]=0;
}
}
for (let i = 1; i <= k; i++)
{
for (let j = 1; j <= k; j++)
{
if (i < k)
{
if (j == i + 1)
{
t[i][j] = 1;
}
else
{
t[i][j] = 0;
}
continue ;
}
t[i][j] = 1;
}
}
t = pow(t, n - 1);
let sum = 0;
for (let i = 1; i <= k; i++)
{
sum += t[1][i] * f1[i];
}
return sum;
}
let n = 4;
document.write(compute(n)+ "<br>" );
n = 5;
document.write(compute(n)+ "<br>" );
n = 10;
document.write(compute(n)+ "<br>" );
</script>
|
Explanation:
We Know For This Question
Transformation Matrix M= [[0,1,0],[0,0,1],[1,1,1]]
Functional Vector F1 = [1,2,4]
for n=2 :
ans = (M X F1)[1]
ans = [2,4,7][1]
ans = 2 //[2,4,7][1] = First cell value of [2,4,7] i.e 2
for n=3 :
ans = (M X M X F1)[1] //M^(3-1) X F1 = M X M X F1
ans = (M X [2,4,7])[1]
ans = [4,7,13][1]
ans = 4
for n = 4 :
ans = (M^(4-1) X F1)[1]
ans = (M X M X M X F1) [1]
ans = (M X [4,7,13])[1]
ans = [7,13,24][1]
ans = 7
for n = 5 :
ans = (M^4 X F1)[1]
ans = (M X [7,13,24])[1]
ans = [13,24,44][1]
ans = 13
Time Complexity:
O(K^3log(n)) //For Computing pow(t,n-1)
For this question K is 3
So Overall Time Complexity is O(27log(n))=O(logn)
Auxiliary Space: O(n^2) because extra space of vector have been used
Method 4: Using four variables
The idea is based on the Fibonacci series but here with 3 sums. we will hold the values of the first three stairs in 3 variables and will use the fourth variable to find the number of ways.
C++
#include <iostream>
using namespace std;
int countWays( int n)
{
int a = 1, b = 2, c = 4;
int d = 0;
if (n == 0 || n == 1 || n == 2)
return n;
if (n == 3)
return c;
for ( int i = 4; i <= n; i++) {
d = c + b + a;
a = b;
b = c;
c = d;
}
return d;
}
int main()
{
int n = 4;
cout << countWays(n);
return 0;
}
|
Java
import java.io.*;
class GFG{
static int countWays( int n)
{
int a = 1 , b = 2 , c = 4 ;
int d = 0 ;
if (n == 0 || n == 1 || n == 2 )
return n;
if (n == 3 )
return c;
for ( int i = 4 ; i <= n; i++)
{
d = c + b + a;
a = b;
b = c;
c = d;
}
return d;
}
public static void main(String[] args)
{
int n = 4 ;
System.out.println(countWays(n));
}
}
|
Python3
def countWays(n):
a = 1
b = 2
c = 4
d = 0
if (n = = 0 or n = = 1 or n = = 2 ):
return n
if (n = = 3 ):
return c
for i in range ( 4 ,n + 1 ):
d = c + b + a
a = b
b = c
c = d
return d
n = 4
print (countWays(n))
|
C#
using System;
class GFG{
static int countWays( int n)
{
int a = 1, b = 2, c = 4;
int d = 0;
if (n == 0 || n == 1 || n == 2)
return n;
if (n == 3)
return c;
for ( int i = 4; i <= n; i++)
{
d = c + b + a;
a = b;
b = c;
c = d;
}
return d;
}
public static void Main(String[] args)
{
int n = 4;
Console.Write(countWays(n));
}
}
|
Javascript
<script>
function countWays( n)
{
var a = 1, b = 2, c = 4;
var d = 0;
if (n == 0 || n == 1 || n == 2)
return n;
if (n == 3)
return c;
for ( var i = 4; i <= n; i++)
{
d = c + b + a;
a = b;
b = c;
c = d;
}
return d;
}
var n = 4;
document.write(countWays(n));
</script>
|
Time Complexity: O(n)
Auxiliary Space: O(1), since no extra space has been taken.
Method 5: DP using memoization(Top down approach)
We can avoid the repeated work done in method 1(recursion) by storing the number of ways calculated so far.
We just need to store all the values in an array.
C++
#include <bits/stdc++.h>
using namespace std;
class GFG {
private :
int findStepHelper( int n, vector< int >& dp)
{
if (n == 0)
return 1;
else if (n < 0)
return 0;
if (dp[n] != -1) {
return dp[n];
}
return dp[n] = findStepHelper(n - 3, dp)
+ findStepHelper(n - 2, dp)
+ findStepHelper(n - 1, dp);
}
public :
int findStep( int n)
{
vector< int > dp(n + 1, -1);
return findStepHelper(n, dp);
}
};
int main()
{
GFG g;
int n = 4;
cout << g.findStep(n);
return 0;
}
|
Java
import java.io.*;
import java.util.*;
class GFG
{
static class gfg {
private int findStepHelper( int n, int [] dp)
{
if (n == 0 )
return 1 ;
else if (n < 0 )
return 0 ;
if (dp[n] != - 1 ) {
return dp[n];
}
return dp[n] = findStepHelper(n - 3 , dp)
+ findStepHelper(n - 2 , dp)
+ findStepHelper(n - 1 , dp);
}
public int findStep( int n)
{
int [] dp = new int [n + 1 ];
Arrays.fill(dp,- 1 );
return findStepHelper(n, dp);
}
};
public static void main(String args[])
{
gfg g = new gfg();
int n = 4 ;
System.out.println(g.findStep(n));
}
}
|
Python3
class GFG:
def findStepHelper( self , n, dp):
if (n = = 0 ):
return 1
elif (n < 0 ):
return 0
if (dp[n] ! = - 1 ):
return dp[n]
dp[n] = self .findStepHelper(n - 3 , dp) + self .findStepHelper(n - 2 , dp) + self .findStepHelper(n - 1 , dp)
return dp[n]
def findStep( self , n):
dp = [ - 1 for i in range (n + 1 )]
return self .findStepHelper(n, dp)
g = GFG()
n = 4
print (g.findStep(n))
|
C#
using System;
class GFG {
static int findStepHelper( int n, int [] dp)
{
if (n == 0)
return 1;
else if (n < 0)
return 0;
if (dp[n] != -1) {
return dp[n];
}
return dp[n] = findStepHelper(n - 3, dp)
+ findStepHelper(n - 2, dp)
+ findStepHelper(n - 1, dp);
}
static int findStep( int n)
{
int [] dp = new int [n + 1];
for ( int i = 0; i <= n; i++) {
dp[i] = -1;
}
return findStepHelper(n, dp);
}
static void Main()
{
int n = 4;
Console.Write(findStep(n));
}
}
|
Javascript
<script>
class GFG {
findStepHelper(n,dp)
{
if (n == 0)
return 1;
else if (n < 0)
return 0;
if (dp[n] != -1) {
return dp[n];
}
return dp[n] = this .findStepHelper(n - 3, dp)
+ this .findStepHelper(n - 2, dp)
+ this .findStepHelper(n - 1, dp);
}
findStep(n)
{
let dp = new Array(n + 1).fill(-1);
return this .findStepHelper(n, dp);
}
};
let g = new GFG();
let n = 4;
document.write(g.findStep(n));
</script>
|
Complexity Analysis:
- Time Complexity: O(n). Only one traversal of the array is needed. So Time Complexity is O(n).
- Space Complexity: O(n). To store the values in a DP, n extra space is needed. Also, stack space for recursion is needed which is again O(n)
Feeling lost in the world of random DSA topics, wasting time without progress? It's time for a change! Join our DSA course, where we'll guide you on an exciting journey to master DSA efficiently and on schedule.
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 geeks!
Last Updated :
20 Jul, 2023
Like Article
Save Article