Table of contents
1.
Introduction
2.
Problem Statement
2.1.
Input
2.2.
Output
3.
Method 1: Egg Dropping Puzzle Using Recursion
3.1.
Algorithm
3.2.
Program
3.3.
C
3.4.
C++
3.5.
Python
3.6.
Java
3.7.
Javascript
3.8.
Input
3.9.
Output
3.10.
Complexity Analysis:
4.
Method 2: DP with Memoization and Binary Search
4.1.
Algorithm
4.2.
Program
4.3.
C
4.4.
C++
4.5.
Python
4.6.
Java
4.7.
Javascript
4.8.
Complexity Analysis
5.
Frequently Asked Questions
5.1.
What is the egg drop problem?
5.2.
How do you solve an egg dropping problem?
5.3.
What are the different methods of egg drop problem?
6.
Conclusion
Last Updated: Apr 24, 2024
Easy

Egg dropping problem

Author Pranav Gautam
2 upvotes
Career growth poll
Do you think IIT Guwahati certified course can help you in your career?

Introduction

Egg dropping problem is a very famous coding problem that requires a bit thinking. The problem statement is as follows. We are given a multi story building, and some number of eggs. We want to know from which floors, if we drop a egg, it will break.  

egg dropping problem

It’s a Monday in Coders’ world. You are about to get a new problem. There is a building with floors 1 to ‘FLOORS’. You are given a basket full of identical eggs. ‘EGGS’ identical eggs. For a better understanding, refer to the figure given below.

Egg dropping problem

As the eggs are identical, they follow the same properties. These properties are given below:

  1. Each egg breaks only if it is dropped from a certain floor ‘EGGBREAKER’ or above.
  2. An egg that is not broken after being dropped from a floor can be used to drop again.


Also Read, Byte Array to String

Problem Statement

As discussed in the introduction section, you are given the following details:

  1. ‘FLOORS’: Total number of floors in the building.
  2.  ‘EGGS’ : Total number of eggs in the basket.
  3.  Your task is to find the minimum number of egg drops required in the worst case to find out the ‘EGGBREAKER’ floor. 

Dropping from different floors leads to a different number of moves required to find the ‘EGGBREAKER’ floor.  

Input

Enter Eggs: 2
Enter Floors: 6

Output

Minimum number of moves required:  3

Method 1: Egg Dropping Puzzle Using Recursion

Recursion is all about using a top-down approach. Every recursion solution recipe has the following ingredients:

Step 1: A problem with bigger input is broken down into the same problem with smaller inputs. 

Step 2: The process keeps repeating until the breakdown is not possible anymore. In other words, recursion stops when we hit the base case. 

Step 3: The outputs of smaller problems are combined to compute problems with bigger inputs.

Can we use recursion for the given problem? Let’s see if our unique Egg dropping problem contains all the ingredients for our recursion recipe. 

  1. A part of the building is also a type of smaller building. Similarly, a subset of eggs from the basket can also be considered as a smaller input. Thus, a problem with a larger input can be divided into subproblems with smaller inputs. Recursive calls create subproblems. 
    Consider an egg dropped from a certain floor (say ‘CURRENT_FLOOR’). Whatever the outcome be, possible next moves are as follows:
    a. The egg broke after falling from the ‘CURRENT_FLOOR’. We can drop the next egg from a floor smaller than ‘CURRENT_FLOOR’. The ‘EGGS’ is decreased by 1. For this, the recursive call is 
                                    FUNCTION(‘CURRENT_FLOOR’ - 1, ‘EGGS’ - 1)
    b.The egg did not break after falling from the ‘CURRENT_FLOOR’. ‘EGGS’ is still the same. Drop the egg from the floor above the ‘CURRENT_FLOOR’. For this, the recursive call is 2. 
                                    FUNCTION(‘FLOORS’ - ‘CURRENT_FLOOR’, ‘EGGS’ )
     
  2. Can you guess the base case? This problem has two following base cases:
    a. If ‘EGGS’ is equal to 1, then the only way to find out the ‘EGG_BREAKER’ floor is by starting to drop the egg from the 1st floor to all the way up.
    b. If  ‘TOTAL_FLOOR’ is equal to 1, then only one egg drop is required to find if it is an ‘EGG_BREAKER’ floor. Also, if the ‘TOTAL_FLOOR’ is equal to 0, then no egg drop is required as no ‘EGG_BREAKER’ floor is possible.
     
  3. How to combine outputs of all the subproblems? As discussed in the Understanding the Problem section, we need to find the minimum number of egg drops in the worst case. For the worst case, find the maximum of all the outputs of the recursive calls for ‘CURRENT_FLOOR’. To find the minimum number of egg drops for the given ‘FLOORS’ and ‘EGGS’, return the minimum of the result of egg drops from all the floors. 

    The problem has all the ingredients for our recursion recipe. Refer to the algorithm given below for a better understanding.

Algorithm

  • If ‘FLOORS’ is less than or equal to 1, then:
    • Return ‘FLOORS’.
  • If ‘EGGS’ is equal to 1, then:
    • Return ‘EGGS’ .
  • Set ‘RESULT’ equal to the maximum value possible (INT_MAX).
  • Loop ‘CURRENT_FLOOR’ from 1 to ‘FLOORS’.
    • Set ‘MOVES_FOR_UNBROKEN_EGGS’ = recursive call with arguments (‘FLOORS’ - ‘CURRENT_FLOOR’ , ‘EGGS’ ).
    • Set  ‘MOVES_FOR_BROKEN_EGGS’ = recursive call with arguments (‘CURRENT_FLOOR’  - 1, ‘EGGS’  - 1).
    • Set ‘WORST_CASE’ = 1 + max(‘MOVES_FOR_UNBROKEN_EGGS’ , ‘MOVES_FOR_BROKEN_EGGS’ ). (1 is added to count the current move).
    • Set ‘RESULT’ = min(‘RESULT’ , ‘WORST_CASE’ ).
  • Return ‘RESULT’

Program

  • C
  • C++
  • Python
  • Java
  • Javascript

C

#include <stdio.h>
#include <limits.h>

int eggDrop(int eggs, int floors) {
if (floors <= 1)
return floors;
if (eggs == 1)
return floors;

int result = INT_MAX;
for (int currentFloor = 1; currentFloor <= floors; currentFloor++) {
int movesForUnbrokenEggs = eggDrop(eggs, floors - currentFloor);
int movesForBrokenEggs = eggDrop(eggs - 1, currentFloor - 1);
int worstCase = 1 + ((movesForUnbrokenEggs > movesForBrokenEggs) ? movesForUnbrokenEggs : movesForBrokenEggs);
result = (result < worstCase) ? result : worstCase;
}
return result;
}

int main() {
int eggs, floors;
printf("Enter Eggs: ");
scanf("%d", &eggs);
printf("Enter Floors: ");
scanf("%d", &floors);
printf("Minimum number of moves required: %d", eggDrop(eggs, floors));
return 0;
}
You can also try this code with Online C Compiler
Run Code

C++

#include <iostream>
#include <limits.h>
using namespace std;

int eggDrop(int eggs, int floors)
{

// Base Case.
if (floors <= 1)
return floors;
if (eggs == 1)
return floors;

int result = INT_MAX;
for (int currentFloor = 1; currentFloor <= floors; currentFloor++)
{
// Recursive Calls.
int movesForUnbrokenEggs = eggDrop(eggs, floors - currentFloor);
int movesForBrokenEggs = eggDrop(eggs - 1, currentFloor - 1);

// Choosing the worst case from the recursive calls.
// Adding 1 for the move to make a recursive call.
int worstCase = 1 + max(movesForUnbrokenEggs, movesForBrokenEggs);

// Comparing moves required in the worst case to the minimum number of moves required in all the cases.
result = min(result, worstCase);
}
return result ;
}

int main()
{
int eggs, floors;
cout << "Enter Eggs: ";
cin >> eggs;
cout << "Enter Floors: ";
cin >> floors;
cout << "Minimum number of moves required: " << eggDrop(eggs, floors);
}
You can also try this code with Online C++ Compiler
Run Code

Python

def eggDrop(eggs, floors):
if floors <= 1:
return floors
if eggs == 1:
return floors

result = float('inf')
for currentFloor in range(1, floors + 1):
movesForUnbrokenEggs = eggDrop(eggs, floors - currentFloor)
movesForBrokenEggs = eggDrop(eggs - 1, currentFloor - 1)
worstCase = 1 + max(movesForUnbrokenEggs, movesForBrokenEggs)
result = min(result, worstCase)
return result

eggs = int(input("Enter Eggs: "))
floors = int(input("Enter Floors: "))
print("Minimum number of moves required:", eggDrop(eggs, floors))
You can also try this code with Online Python Compiler
Run Code

Java

import java.util.Scanner;

public class EggDrop {
public static int eggDrop(int eggs, int floors) {
if (floors <= 1)
return floors;
if (eggs == 1)
return floors;

int result = Integer.MAX_VALUE;
for (int currentFloor = 1; currentFloor <= floors; currentFloor++) {
int movesForUnbrokenEggs = eggDrop(eggs, floors - currentFloor);
int movesForBrokenEggs = eggDrop(eggs - 1, currentFloor - 1);
int worstCase = 1 + Math.max(movesForUnbrokenEggs, movesForBrokenEggs);
result = Math.min(result, worstCase);
}
return result;
}

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter Eggs: ");
int eggs = scanner.nextInt();
System.out.print("Enter Floors: ");
int floors = scanner.nextInt();
System.out.println("Minimum number of moves required: " + eggDrop(eggs, floors));
}
}
You can also try this code with Online Java Compiler
Run Code

Javascript

function eggDrop(eggs, floors) {
if (floors <= 1)
return floors;
if (eggs == 1)
return floors;

let result = Infinity;
for (let currentFloor = 1; currentFloor <= floors; currentFloor++) {
let movesForUnbrokenEggs = eggDrop(eggs, floors - currentFloor);
let movesForBrokenEggs = eggDrop(eggs - 1, currentFloor - 1);
let worstCase = 1 + Math.max(movesForUnbrokenEggs, movesForBrokenEggs);
result = Math.min(result, worstCase);
}
return result;
}

const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

rl.question("Enter Eggs: ", (eggs) => {
rl.question("Enter Floors: ", (floors) => {
console.log("Minimum number of moves required: " + eggDrop(parseInt(eggs), parseInt(floors)));
rl.close();
});
});
You can also try this code with Online Javascript Compiler
Run Code

Input

Enter Eggs: 2
Enter Floors: 6

Output

Minimum number of moves required:  3

Complexity Analysis:

Time complexity: Two recursive calls are made for every combination of eggs and floors. So, the total number of recursive calls is 2min(EGGS, FLOORS). A loop runs in the code in linear time from 1 to ‘FLOORS’ for each recursive call. So, the time complexity of code is O(FLOORS * 2min(EGGS, FLOORS) ).

Space complexity: Since the total number of recursive calls is 2min(EGGS, FLOORS). The depth of the recursion tree would be min(EGGS, FLOORS). Therefore, the total space complexity required due to recursive call stack is O(min(EGGS, FLOORS)).

Read More - Time Complexity of Sorting Algorithms

Method 2: DP with Memoization and Binary Search

A recursion is a straightforward  approach, but it gives a TLE when brought to use. Take a look at the recursion tree shown in the figure below. For simplicity, we are considering only one floor as the current floor.

DP with Memoization and Binary Search

With the increase in the size of the recursive tree, the recursive function is called multiple times with the same input argument. Memoization can prune the recursive tree by storing the results of recursive calls. All you need to do is to make some tiny changes in our recursion recipe. 

What should we memoize? You might have noticed that the output depends on ‘FLOORS’ and ‘EGGS’ for every function call.  The maximum number of ‘FLOORS’ - ‘EGGS’ pairs is possible as the function arguments are (‘FLOORS’ + 1) x (‘EGGS’ + 1). We can use a 2-D (say ‘MEMO’’) array to store the output of these possible pairs. Extra row and column is added because the array is 0-indexed and arguments are 1-indexed.

Can we optimize it more? Yes, we can. In the Method 1:Recursion section, we used a linear search to check if the ‘CURRENT_FLOOR’ is an ‘EGG_BREAKER’ floor. This linear search runs in O(‘FLOOR’) time. The linear search can be replaced as binary search for further optimization. These minor modifications in our recursion algorithm can help us avoid the exponential time complexity. Refer to the algorithm given below for a better understanding.

Algorithm

  • Initialize a ‘MEMO’ vector of size (‘FLOORS’ + 1) x (‘EGGS’ + 1) with value -1.
  • If ‘FLOORS’ is less than or equal to 1, then:
    • Return ‘FLOORS’.
  • If ‘EGGS’ is equal to 1, then:
    • Return ‘EGGS’ .
  • If MEMO[‘FLOORS’ ][‘EGGS’ ] is not equal to -1, then:
    • Return MEMO[‘FLOORS’ ][‘EGGS’ ]
  • Set ‘RESULT’ equal to the maximum value possible (INT_MAX).
  • Set ‘LOW’ = 1 and ‘HIGH’ = ‘FLOORS’ for binary search.
  • While ‘LOW’ < ‘HIGH’, do:
    • Set ‘MID_FLOOR’ = ‘LOW’  + (‘HIGH’ - ‘LOW’ ) / 2
    • Declare ‘MOVES_FOR_UNBROKEN_EGGS’.
    • If MEMO[‘FLOORS’ - ‘MID_FLOOR’ ][‘EGGS’] is equal to -1, then:
      • Set ‘MOVES_FOR_UNBROKEN_EGGS’ = recursive call with arguments (‘FLOORS’ - ‘MID_FLOOR’, ‘EGGS’ ).
    • Else:
      • Set ‘MOVES_FOR_UNBROKEN_EGGS’ = MEMO[‘FLOORS’ - ‘MID_FLOOR’ ][‘EGGS’].
    • Declare ‘MOVES_FOR_BROKEN_EGGS’.
    • If MEMO[‘MID_FLOOR’  - 1][‘EGGS’ - 1] is equal to -1, then:
      • Set ‘MOVES_FOR_BROKEN_EGGS’ = recursive call with arguments (‘MID_FLOOR’ - 1, ‘EGGS’ - 1).
    • Else:
      • Set ‘MOVES_FOR_BROKEN_EGGS’ = MEMO[‘MID_FLOOR’ - 1][‘EGGS’ - 1]
    • If ‘MOVES_FOR_BROKEN_EGGS’ < ‘MOVES_FOR_UNBROKEN_EGGS’,  then:
      • Set ‘LOW’ = ‘MOVES_FOR_BROKEN_EGGS’ + 1.
    • Else: 
      • Set ‘HIGH’ = ‘MOVES_FOR_UNBROKEN_EGGS’.
    • Set ‘WORST_CASE’ = 1 + max(‘MOVES_FOR_BROKEN_EGGS’, ‘MOVES_FOR_UNBROKEN_EGGS’).
    • Set ‘RESULT’ = min(‘RESULT’, ‘WORST_CASE’ ).
  • Before Return, Set MEMO[‘FLOORS’ ][‘EGGS’ ] = ‘RESULT’.
  • Return ‘RESULT’

Program

  • C
  • C++
  • Python
  • Java
  • Javascript

C

#include <stdio.h>
#include <limits.h>
#include <string.h>

int memo[101][10001];

int eggDrop(int eggs, int floors) {
if (floors <= 1)
return floors;
if (eggs == 1)
return floors;
if (memo[eggs][floors] != -1)
return memo[eggs][floors];

int ans = INT_MAX, movesForUnbrokenEggs = 0, movesForBrokenEggs = 0;
int low = 1, high = floors;

while (low < high) {
int mid = low + (high - low) / 2;
if (memo[eggs - 1][mid - 1] != -1)
movesForBrokenEggs = memo[eggs - 1][mid - 1];
else
movesForBrokenEggs = eggDrop(eggs - 1, mid - 1);
if (memo[eggs][floors - mid] != -1)
movesForUnbrokenEggs = memo[eggs][floors - mid];
else
movesForUnbrokenEggs = eggDrop(eggs, floors - mid);

if (movesForBrokenEggs > movesForUnbrokenEggs)
high = mid;
else
low = mid + 1;

int temp = 1 + ((movesForBrokenEggs > movesForUnbrokenEggs) ? movesForBrokenEggs : movesForUnbrokenEggs);
ans = (ans < temp) ? ans : temp;
}

return memo[eggs][floors] = ans;
}

int main() {
int eggs, floors;
printf("Enter Eggs: ");
scanf("%d", &eggs);
printf("Enter Floors: ");
scanf("%d", &floors);

memset(memo, -1, sizeof(memo));

printf("Minimum number of moves required: %d", eggDrop(eggs, floors));
return 0;
}
You can also try this code with Online C Compiler
Run Code

C++

#include <iostream>
#include <climits>
#include <vector>
#include <cstring>
using namespace std;
int memo[101][10001];

int eggDrop(int eggs, int floors)
{
// If 'FLOORS' = 0 no drop needed.
// If FL'OORS = 1 only 1 drop needed.
if (floors <= 1)
return floors;

// If 'EGGS' = 1, gradually drop the egg from 1st floor to all the way up.
if (eggs == 1)
return floors;

// If answer for given number of eggs and floors, return it.
if (memo[eggs][floors] != -1)
return memo[eggs][floors];

// 'ANS' returns the final answer for current number of eggs and floors.
int ans = INT_MAX, movesForUnbrokenEgss = 0, movesForBrokenEgss = 0;

// 'LOW' and 'HIGH' pointers for binary search.
int low = 1, high = floors;

while (low < high)
{

// Computing mid floor to drop the egg from the mid floor.
int mid = low + (high - low) / 2;

// 'MOVES_FOR_BROKEN_EGGS' to store answer if egg is broken after falling from 'MID' floor.
if (memo[eggs - 1][mid - 1] != -1)
movesForBrokenEgss = memo[eggs - 1][mid - 1];
else
movesForBrokenEgss = eggDrop(eggs - 1, mid - 1);

// 'MOVES_FOR_UNBROKEN_EGGS' to store answer if egg is not broken after falling from 'MID' floor.
if (memo[eggs][floors - mid] != -1)
movesForUnbrokenEgss = memo[eggs][floors - mid];
else
movesForUnbrokenEgss = eggDrop(eggs, floors - mid);

// Move the binary search towards the case where number of egg drops are more.
if (movesForBrokenEgss > movesForUnbrokenEgss)
high = mid;
else
low = mid + 1;

// Maximum number of egg drops for both the case.
// Add 1 to represent the current egg drop.
int temp = 1 + max(movesForBrokenEgss, movesForUnbrokenEgss);

// Choose minimum of all the worst cases.
ans = min(ans, temp);
}

// Storing the output for current numbers of eggs and floors.
return memo[eggs][floors] = ans;
}

int main()
{
int eggs, floors;
cout << "Enter Eggs: ";
cin >> eggs;
cout << "Enter Floors: ";
cin >> floors;

// Initialize memo array with value -1.
memset(memo, -1, sizeof(memo));

cout << "Minimum number of moves required: " << eggDrop(eggs, floors);
}
You can also try this code with Online C++ Compiler
Run Code

Python

memo = [[-1] * 10001 for _ in range(101)]

def eggDrop(eggs, floors):
if floors <= 1:
return floors
if eggs == 1:
return floors
if memo[eggs][floors] != -1:
return memo[eggs][floors]

ans = float('inf')
low, high = 1, floors

while low < high:
mid = low + (high - low) // 2
movesForBrokenEggs = memo[eggs - 1][mid - 1] if memo[eggs - 1][mid - 1] != -1 else eggDrop(eggs - 1, mid - 1)
movesForUnbrokenEggs = memo[eggs][floors - mid] if memo[eggs][floors - mid] != -1 else eggDrop(eggs, floors - mid)

if movesForBrokenEggs > movesForUnbrokenEggs:
high = mid
else:
low = mid + 1

temp = 1 + max(movesForBrokenEggs, movesForUnbrokenEggs)
ans = min(ans, temp)

memo[eggs][floors] = ans
return ans

eggs = int(input("Enter Eggs: "))
floors = int(input("Enter Floors: "))
print("Minimum number of moves required:", eggDrop(eggs, floors))
You can also try this code with Online Python Compiler
Run Code

Java

import java.util.Scanner;

public class EggDrop {
static int[][] memo = new int[101][10001];

public static int eggDrop(int eggs, int floors) {
if (floors <= 1)
return floors;
if (eggs == 1)
return floors;
if (memo[eggs][floors] != -1)
return memo[eggs][floors];

int ans = Integer.MAX_VALUE, movesForUnbrokenEggs = 0, movesForBrokenEggs = 0;
int low = 1, high = floors;

while (low < high) {
int mid = low + (high - low) / 2;
movesForBrokenEggs = (memo[eggs - 1][mid - 1] != -1) ? memo[eggs - 1][mid - 1] : eggDrop(eggs - 1, mid - 1);
movesForUnbrokenEggs = (memo[eggs][floors - mid] != -1) ? memo[eggs][floors - mid] : eggDrop(eggs, floors - mid);

if (movesForBrokenEggs > movesForUnbrokenEggs)
high = mid;
else
low = mid + 1;

int temp = 1 + Math.max(movesForBrokenEggs, movesForUnbrokenEggs);
ans = Math.min(ans, temp);
}

memo[eggs][floors] = ans;
return ans;
}

public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.print("Enter Eggs: ");
int eggs = scanner.nextInt();
System.out.print("Enter Floors: ");
int floors = scanner.nextInt();

for (int[] m : memo) {
Arrays.fill(m, -1);
}

System.out.println("Minimum number of moves required: " + eggDrop(eggs, floors));
}
}
You can also try this code with Online Java Compiler
Run Code

Javascript

let memo = new Array(101).fill(null).map(() => new Array(10001).fill(-1));

function eggDrop(eggs, floors) {
if (floors <= 1)
return floors;
if (eggs == 1)
return floors;
if (memo[eggs][floors] != -1)
return memo[eggs][floors];

let ans = Infinity;
let low = 1, high = floors;

while (low < high) {
let mid = low + Math.floor((high - low) / 2);
let movesForBrokenEggs = (memo[eggs - 1][mid - 1] != -1) ? memo[eggs - 1][mid - 1] : eggDrop(eggs - 1, mid - 1);
let movesForUnbrokenEggs = (memo[eggs][floors - mid] != -1) ? memo[eggs][floors - mid] : eggDrop(eggs, floors - mid);

if (movesForBrokenEggs > movesForUnbrokenEggs)
high = mid;
else
low = mid + 1;

let temp = 1 + Math.max(movesForBrokenEggs, movesForUnbrokenEggs);
ans = Math.min(ans, temp);
}

memo[eggs][floors] = ans;
return ans;
}

const readline = require('readline');
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});

rl.question("Enter Eggs: ", (eggs) => {
rl.question("Enter Floors: ", (floors) => {
for (let m of memo) {
m.fill(-1);
}
console.log("Minimum number of moves required: " + eggDrop(parseInt(eggs), parseInt(floors)));
rl.close();
});
});
You can also try this code with Online Javascript Compiler
Run Code

Complexity Analysis

Time Complexity: A binary search is done for every combination of the number of eggs and floors. The maximum number of combinations possible is K x N, where ‘K’ and ‘N’ represent the number of eggs and floors. The time complexity of a binary search operation is log(N), where ‘N’ represents the number of floors given. O(K x NlogN), where ‘K’ and ‘N’ represent the number of eggs and floors respectively. 

Space Complexity: Additional space is required to store the results of the recursive function in the memo. The size of the memo depends on the number of eggs and floors given in the input. So, the space complexity is O(K x N), where ‘K’ and ‘N’ represent the number of eggs and floors, respectively.

Must Read Recursive Binary Search.

Frequently Asked Questions

What is the egg drop problem?

Egg dropping problem is a very famous coding problem that requires a bit thinking. The problem statement is as follows. We are given a multi story building, and some number of eggs. We want to know from which floors, if we drop a egg, it will break.  

How do you solve an egg dropping problem?

The egg dropping problem is solved using dynamic programming. Recursively explore scenarios of dropping eggs from different floors, memoize results, and return the minimum attempts needed to solve.

What are the different methods of egg drop problem?

Different methods for solving the egg drop problem include dynamic programming, binary search, and mathematical optimization. Each method offers unique trade-offs in terms of complexity and efficiency. 

Conclusion

There’s usually more than one approach to a solution. Yes, it feels sluggish to solve the same problem again and again. But, we should always try to look for more ways to solve a problem. After all, it’s an excellent way to practice more than one algorithm or technique from a single problem.

Try to memoize the code if some value is computed again and again. To become a good coder, you need other ingredients too. You need to have a common sense with a bit of mind that’s ready to make adjustments to a solution. Adjustments that can make it more efficient. You can practice memoization and many more cool techniques using our free practice platform Coding Ninjas Studio.  So, keep practicing. That’s what good coders do.

Happy Coding!

Live masterclass