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.
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)
// JavaScript Program to find n-th stair using step size
// 1 or 2 or 3.
// Returns count of ways to reach n-th stair
// using 1 or 2 or 3 steps.
functionfindStep(n)
{
if(n == 0)
return1;
elseif(n < 0)
return0;
else
returnfindStep(n - 3) + findStep(n - 2)
+ findStep(n - 1);
}
// Driver code
let n = 4;
document.write(findStep(n));
// This code is contributed by Surbhi Tyagi.
</script>
PHP
<?php
// PHP Program to find n-th stair
// using step size 1 or 2 or 3.
// Returns count of ways to
// reach n-th stair using
// 1 or 2 or 3 steps.
functionfindStep($n)
{
if( $n== 0)
return1;
elseif($n< 0)
return0;
else
returnfindStep($n- 3) +
findStep($n- 2) +
findStep($n- 1);
}
// Driver code
$n= 4;
echofindStep($n);
// This code is contributed by m_kit
?>
Output
7
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.
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]
// Computing T^(n-1) and Setting Transformation matrix T
// to T^(n-1)
t = pow(t, n - 1);
intsum = 0;
// Computing first cell (row=1,col=1) For Resultant
// Matrix TXF
for(inti = 1; i <= k; i++) {
sum += t[1][i] * f1[i];
}
returnsum;
}
intmain()
{
intn = 4;
cout << compute(n) << endl;
n = 5;
cout << compute(n) << endl;
n = 10;
cout << compute(n) << endl;
return0;
}
Java
importjava.io.*;
importjava.util.*;
classGFG {
staticintk = 3;
// Multiply Two Matrix Function
staticint[][] multiply(int[][] A, int[][] B)
{
// Third matrix to store multiplication
// of Two matrix9*
int[][] C = newint[k + 1][k + 1];
for(inti = 1; i <= k; i++) {
for(intj = 1; j <= k; j++) {
for(intx = 1; x <= k; x++) {
C[i][j]
= (C[i][j] + (A[i][x] * B[x][j]));
}
}
}
returnC;
}
// Optimal Way For finding pow(t,n)
// If n Is Odd then It Will be t*pow(t,n-1)
// else return pow(t,n/2)*pow(t,n/2)
staticint[][] pow(int[][] t, intn)
{
// Base Case
if(n == 1) {
returnt;
}
// Recurrence Case
if((n & 1) != 0) {
returnmultiply(t, pow(t, n - 1));
}
else{
int[][] X = pow(t, n / 2);
returnmultiply(X, X);
}
}
staticintcompute(intn)
{
// Base Case
if(n == 0)
return1;
if(n == 1)
return1;
if(n == 2)
return2;
// Function int(indexing 1 )
// that is [1,2]
intf1[] = newint[k + 1];
f1[1] = 1;
f1[2] = 2;
f1[3] = 4;
// Constructing Transformation Matrix that will be
/*[[0,1,0],[0,0,1],[3,2,1]]
*/
int[][] t = newint[k + 1][k + 1];
for(inti = 1; i <= k; i++) {
for(intj = 1; j <= k; j++) {
if(i < k) {
// Store 1 in cell that is next to
// diagonal of Matrix else Store 0 in
// cell
if(j == i + 1) {
t[i][j] = 1;
}
else{
t[i][j] = 0;
}
continue;
}
// Last Row - store the Coefficients
// in reverse order
t[i][j] = 1;
}
}
// Computing T^(n-1) and Setting
// Transformation matrix T to T^(n-1)
t = pow(t, n - 1);
intsum = 0;
// Computing first cell (row=1,col=1)
// For Resultant Matrix TXF
for(inti = 1; i <= k; i++) {
sum += t[1][i] * f1[i];
}
returnsum;
}
// Driver Code
publicstaticvoidmain(String[] args)
{
// Input
intn = 4;
System.out.println(compute(n));
n = 5;
System.out.println(compute(n));
n = 10;
System.out.println(compute(n));
}
}
// This code is contributed by Shubhamsingh10
Python3
k =3
# Multiply Two Matrix Function
defmultiply(A, B):
# third matrix to store multiplication of Two matrix9*
C =[[0forx inrange(k+1)] fory inrange(k+1)]
fori inrange(1, k+1):
forj inrange(1, k+1):
forx inrange(1, k+1):
C[i][j] =(C[i][j] +(A[i][x] *B[x][j]))
returnC
# Optimal Way For finding pow(t,n)
# If n Is Odd then It Will be t*pow(t,n-1)
# else return pow(t,n/2)*pow(t,n/2)
defpow(t, n):
# base Case
if(n ==1):
returnt
# Recurrence Case
if(n & 1):
returnmultiply(t, pow(t, n -1))
else:
X =pow(t, n //2)
returnmultiply(X, X)
defcompute(n):
# base Case
if(n ==0):
return1
if(n ==1):
return1
if(n ==2):
return2
# Function Vector(indexing 1 )
# that is [1,2]
f1 =[0]*(k +1)
f1[1] =1
f1[2] =2
f1[3] =4
# Constructing Transformation Matrix that will be
# [[0,1,0],[0,0,1],[3,2,1]]
t =[[0forx inrange(k+1)] fory inrange(k+1)]
fori inrange(1, k+1):
forj inrange(1, k+1):
if(i < k):
# Store 1 in cell that is next to diagonal of Matrix else Store 0 in
# cell
if(j ==i +1):
t[i][j] =1
else:
t[i][j] =0
continue
# Last Row - store the Coefficients in reverse order
t[i][j] =1
# Computing T^(n-1) and Setting Transformation matrix T to T^(n-1)
t =pow(t, n -1)
sum=0
# Computing first cell (row=1,col=1) For Resultant Matrix TXF
fori inrange(1, k+1):
sum+=t[1][i] *f1[i]
returnsum
# Driver Code
n =4
print(compute(n))
n =5
print(compute(n))
n =10
print(compute(n))
# This code is contributed by Shubhamsingh10
C#
// C# program for the above approach
usingSystem;
classGFG {
staticintk = 3;
// Multiply Two Matrix Function
staticint[, ] multiply(int[, ] A, int[, ] B)
{
// Third matrix to store multiplication
// of Two matrix9*
int[, ] C = newint[k + 1, k + 1];
for(inti = 1; i <= k; i++) {
for(intj = 1; j <= k; j++) {
for(intx = 1; x <= k; x++) {
C[i, j]
= (C[i, j] + (A[i, x] * B[x, j]));
}
}
}
returnC;
}
// Optimal Way For finding pow(t,n)
// If n Is Odd then It Will be t*pow(t,n-1)
// else return pow(t,n/2)*pow(t,n/2)
staticint[, ] pow(int[, ] t, intn)
{
// Base Case
if(n == 1) {
returnt;
}
// Recurrence Case
if((n & 1) != 0) {
returnmultiply(t, pow(t, n - 1));
}
else{
int[, ] X = pow(t, n / 2);
returnmultiply(X, X);
}
}
staticintcompute(intn)
{
// Base Case
if(n == 0)
return1;
if(n == 1)
return1;
if(n == 2)
return2;
// Function int(indexing 1 )
// that is [1,2]
int[] f1 = newint[k + 1];
f1[1] = 1;
f1[2] = 2;
f1[3] = 4;
// Constructing Transformation Matrix that will be
/*[[0,1,0],[0,0,1],[3,2,1]]
*/
int[, ] t = newint[k + 1, k + 1];
for(inti = 1; i <= k; i++) {
for(intj = 1; j <= k; j++) {
if(i < k) {
// Store 1 in cell that is next to
// diagonal of Matrix else Store 0 in
// cell
if(j == i + 1) {
t[i, j] = 1;
}
else{
t[i, j] = 0;
}
continue;
}
// Last Row - store the Coefficients
// in reverse order
t[i, j] = 1;
}
}
// Computing T^(n-1) and Setting
// Transformation matrix T to T^(n-1)
t = pow(t, n - 1);
intsum = 0;
// Computing first cell (row=1,col=1)
// For Resultant Matrix TXF
for(inti = 1; i <= k; i++) {
sum += t[1, i] * f1[i];
}
returnsum;
}
// Driver Code
staticpublicvoidMain()
{
// Input
intn = 4;
Console.WriteLine(compute(n));
n = 5;
Console.WriteLine(compute(n));
n = 10;
Console.WriteLine(compute(n));
}
}
// This code is contributed by Shubhamsingh10
Javascript
<script>
let k = 3;
// Multiply Two Matrix Function
functionmultiply(A,B)
{
// Third matrix to store multiplication
// of Two matrix9*
let C = newArray(k + 1);
for(let i=0;i<k+1;i++)
{
C[i]=newArray(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]));
}
}
}
returnC;
}
// Optimal Way For finding pow(t,n)
// If n Is Odd then It Will be t*pow(t,n-1)
// else return pow(t,n/2)*pow(t,n/2)
functionpow(t,n)
{
// Base Case
if(n == 1)
{
returnt;
}
// Recurrence Case
if((n & 1) != 0)
{
returnmultiply(t, pow(t, n - 1));
}
else
{
let X = pow(t, n / 2);
returnmultiply(X, X);
}
}
functioncompute(n)
{
// Base Case
if(n == 0) return1;
if(n == 1) return1;
if(n == 2) return2;
// Function int(indexing 1 )
// that is [1,2]
let f1=newArray(k + 1);
f1[1] = 1;
f1[2] = 2;
f1[3] = 4;
// Constructing Transformation Matrix that will be
/*[[0,1,0],[0,0,1],[3,2,1]]
*/
let t = newArray(k + 1);
for(let i=0;i<k+1;i++)
{
t[i]=newArray(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)
{
// Store 1 in cell that is next to
// diagonal of Matrix else Store 0 in
// cell
if(j == i + 1)
{
t[i][j] = 1;
}
else
{
t[i][j] = 0;
}
continue;
}
// Last Row - store the Coefficients
// in reverse order
t[i][j] = 1;
}
}
// Computing T^(n-1) and Setting
// Transformation matrix T to T^(n-1)
t = pow(t, n - 1);
let sum = 0;
// Computing first cell (row=1,col=1)
// For Resultant Matrix TXF
for(let i = 1; i <= k; i++)
{
sum += t[1][i] * f1[i];
}
returnsum;
}
// Driver Code
// Input
let n = 4;
document.write(compute(n)+"<br>");
n = 5;
document.write(compute(n)+"<br>");
n = 10;
document.write(compute(n)+"<br>");
// This code is contributed by avanitrachhadiya2155
</script>
Output
7
13
274
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++
// A C++ program to count number of ways
// to reach nth stair when
#include <iostream>
usingnamespacestd;
// A recursive function used by countWays
intcountWays(intn)
{
inta = 1, b = 2, c = 4; // declaring three variables
// and holding the ways
// for first three stairs
intd = 0; // fourth variable
if(n == 0 || n == 1 || n == 2)
returnn;
if(n == 3)
returnc;
for(inti = 4; i <= n; i++) { // starting from 4 as
d = c + b + a; // already counted for 3 stairs
a = b;
b = c;
c = d;
}
returnd;
}
// Driver program to test above functions
intmain()
{
intn = 4;
cout << countWays(n);
return0;
}
// This code is contributed by Naveen Shah
Java
// A Java program to count number of ways
// to reach nth stair when
importjava.io.*;
classGFG{
// A recursive function used by countWays
staticintcountWays(intn)
{
// Declaring three variables
// and holding the ways
// for first three stairs
inta = 1, b = 2, c = 4;
// Fourth variable
intd = 0;
if(n == 0|| n == 1|| n == 2)
returnn;
if(n == 3)
returnc;
for(inti = 4; i <= n; i++)
{
// Starting from 4 as
// already counted for 3 stairs
d = c + b + a;
a = b;
b = c;
c = d;
}
returnd;
}
// Driver code
publicstaticvoidmain(String[] args)
{
intn = 4;
System.out.println(countWays(n));
}
}
// This code is contributed by shivanisinghss2110
Python3
# A Python program to count number of ways
# to reach nth stair when
# A recursive function used by countWays
defcountWays(n):
# declaring three variables
# and holding the ways
# for first three stairs
a =1
b =2
c =4
d =0# fourth variable
if(n ==0orn ==1orn ==2):
returnn
if(n ==3):
returnc
fori inrange(4,n+1):
# starting from 4 as
d =c +b +a # already counted for 3 stairs
a =b
b =c
c =d
returnd
# Driver program to test above functions
n =4
print(countWays(n))
# This code is contributed by shivanisinghss2110
C#
// A C# program to count number of ways
// to reach nth stair when
usingSystem;
classGFG{
// A recursive function used by countWays
staticintcountWays(intn)
{
// Declaring three variables
// and holding the ways
// for first three stairs
inta = 1, b = 2, c = 4;
// Fourth variable
intd = 0;
if(n == 0 || n == 1 || n == 2)
returnn;
if(n == 3)
returnc;
for(inti = 4; i <= n; i++)
{
// Starting from 4 as
// already counted for 3 stairs
d = c + b + a;
a = b;
b = c;
c = d;
}
returnd;
}
// Driver code
publicstaticvoidMain(String[] args)
{
intn = 4;
Console.Write(countWays(n));
}
}
// This code is contributed by shivanisinghss2110
Javascript
<script>
// A JavaScript program to count number of ways
// to reach nth stair when
// A recursive function used by countWays
functioncountWays( n)
{
// Declaring three variables
// and holding the ways
// for first three stairs
vara = 1, b = 2, c = 4;
// Fourth variable
vard = 0;
if(n == 0 || n == 1 || n == 2)
returnn;
if(n == 3)
returnc;
for(vari = 4; i <= n; i++)
{
// Starting from 4 as
// already counted for 3 stairs
d = c + b + a;
a = b;
b = c;
c = d;
}
returnd;
}
// Driver code
varn = 4;
document.write(countWays(n));
// This code is contributed by shivanisinghss2110
</script>
Output
7
Time Complexity: O(n) AuxiliarySpace: 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++
// C++ Program to find n-th stair using step size
// 1 or 2 or 3.
#include <bits/stdc++.h>
usingnamespacestd;
classGFG {
private:
intfindStepHelper(intn, vector<int>& dp)
{
// Base Case
if(n == 0)
return1;
elseif(n < 0)
return0;
// If subproblems are already calculated
//then return it
if(dp[n] != -1) {
returndp[n];
}
// store the subproblems in the vector
returndp[n] = findStepHelper(n - 3, dp)
+ findStepHelper(n - 2, dp)
+ findStepHelper(n - 1, dp);
}
// Returns count of ways to reach n-th stair
// using 1 or 2 or 3 steps.
public:
intfindStep(intn)
{
vector<int> dp(n + 1, -1);
returnfindStepHelper(n, dp);
}
};
// Driver code
intmain()
{
GFG g;
intn = 4;
cout << g.findStep(n);
return0;
}
Java
/*package whatever //do not write package name here */
importjava.io.*;
importjava.util.*;
classGFG
{
// Java Program to find n-th stair using step size
// 1 or 2 or 3.
staticclassgfg {
privateintfindStepHelper(intn, int[] dp)
{
// Base Case
if(n == 0)
return1;
elseif(n < 0)
return0;
// If subproblems are already calculated
//then return it
if(dp[n] != -1) {
returndp[n];
}
// store the subproblems in the vector
returndp[n] = findStepHelper(n - 3, dp)
+ findStepHelper(n - 2, dp)
+ findStepHelper(n - 1, dp);
}
// Returns count of ways to reach n-th stair
// using 1 or 2 or 3 steps.
publicintfindStep(intn)
{
int[] dp = newint[n + 1];
Arrays.fill(dp,-1);
returnfindStepHelper(n, dp);
}
};
/* Driver program to test above function*/
publicstaticvoidmain(String args[])
{
gfg g = newgfg();
intn = 4;
System.out.println(g.findStep(n));
}
}
// This code is contributed by shinjanpatra
Python3
# Python Program to find n-th stair using step size
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 neveropen!