Given integers n (the height of the tower), m (the maximum size of tiles available), and k (the maximum number of times each tile size can be used), the task is to calculate the number of distinct stable towers of height n that can be built.
Note:
- A stable tower consists of exactly n tiles, each stacked such that no larger tile is placed on a smaller one.
- Two towers are considered different if, at any height h (where 1<=h<=n), they have tiles of different sizes.
Examples:
Input: n = 3, m = 3, k = 1.
Output: 1
Explanation: Possible sequence: [1, 2, 3].
Input: n = 3, m = 3, k = 2.
Output: 7
Explanation: Possible sequences: [1, 1, 2], [1, 1, 3], [1, 2, 2], [1, 2, 3], [1, 3, 3], [2, 2, 3], [2, 3, 3].
Using Recursion - O(k^m) Time and O(m) Space
The main idea for the recursive approach is to build the tower by selecting different numbers of tiles from the largest available tile size, moving to smaller sizes as we progress. For each tile size, we try adding up to k tiles (or fewer, if fewer are needed to reach height n). By reducing both the remaining height n and the largest available tile size m with each recursive call, we explore all valid combinations that maintain the stability condition (no larger tile placed on a smaller one).
The recurrence relation for this solution can be expressed as:
possibleWays(n, m, k) = sum of possibleWays(n - cnt, m - 1, k) for each cnt from 0 to min(k, n), where possibleWays(n, m, k) gives the number of ways to build a tower of height n using up to size m tiles, with a maximum of k tiles of any size allowed.
Base cases:
- ways(0, m, k) = 1, meaning a tower of height 0 has only one possible configuration (using no tiles).
- ways(n, 0, k) = 0, meaning no tower can be built if m is zero and n is greater than zero.
C++
// C++ program to find number of ways to
// make stable towers of given height.
#include <bits/stdc++.h>
using namespace std;
// Recursive function to calculate possible ways to
// form towers of height 'n' using tiles of sizes
// up to 'm' with at most 'k' tiles of each size
int possibleWaysRecur(int n, int m, int k) {
// Base cases:
// If height is 0, there is exactly 1 way (empty tower)
if (n == 0) return 1;
// If no more tile sizes are available,
// no ways can be formed
if (m == 0) return 0;
int ans = 0;
// Try using 'cnt' tiles of the current size
// (from 0 up to 'k' tiles) and make recursive
// calls for remaining height and tiles
for (int cnt = 0; cnt <= k && cnt <= n; cnt++) {
ans += possibleWaysRecur(n - cnt, m - 1, k);
}
return ans;
}
int possibleWays(int n, int m, int k) {
return possibleWaysRecur(n, m, k);
}
int main() {
int n = 3, m = 3, k = 2;
cout << possibleWays(n, m, k) << endl;
return 0;
}
Java
// Java program to find number of ways to
// make stable towers of given height.
class GfG {
static int possibleWaysRecur(int n, int m, int k) {
// Base cases:
// If height is 0, there is exactly 1 way (empty tower)
if (n == 0) return 1;
// If no more tile sizes are available,
// no ways can be formed
if (m == 0) return 0;
int ans = 0;
// Try using 'cnt' tiles of the current size
// (from 0 up to 'k' tiles) and make recursive
// calls for remaining height and tiles
for (int cnt = 0; cnt <= k && cnt <= n; cnt++) {
ans += possibleWaysRecur(n - cnt, m - 1, k);
}
return ans;
}
static int possibleWays(int n, int m, int k) {
return possibleWaysRecur(n, m, k);
}
public static void main(String[] args) {
int n = 3, m = 3, k = 2;
System.out.println(possibleWays(n, m, k));
}
}
Python
# Python program to find number of ways to
# make stable towers of given height.
def possibleWaysRecur(n, m, k):
# Base cases:
# If height is 0, there is exactly 1 way (empty tower)
if n == 0:
return 1
# If no more tile sizes are available,
# no ways can be formed
if m == 0:
return 0
ans = 0
# Try using 'cnt' tiles of the current size
# (from 0 up to 'k' tiles) and make recursive
# calls for remaining height and tiles
for cnt in range(min(k, n) + 1):
ans += possibleWaysRecur(n - cnt, m - 1, k)
return ans
def possibleWays(n, m, k):
return possibleWaysRecur(n, m, k)
if __name__ == "__main__":
n, m, k = 3, 3, 2
print(possibleWays(n, m, k))
C#
// C# program to find number of ways to
// make stable towers of given height.
using System;
class GfG {
static int possibleWaysRecur(int n, int m, int k) {
// Base cases:
// If height is 0, there is exactly 1 way (empty tower)
if (n == 0) return 1;
// If no more tile sizes are available,
// no ways can be formed
if (m == 0) return 0;
int ans = 0;
// Try using 'cnt' tiles of the current size
// (from 0 up to 'k' tiles) and make recursive
// calls for remaining height and tiles
for (int cnt = 0; cnt <= k && cnt <= n; cnt++) {
ans += possibleWaysRecur(n - cnt, m - 1, k);
}
return ans;
}
static int possibleWays(int n, int m, int k) {
return possibleWaysRecur(n, m, k);
}
static void Main() {
int n = 3, m = 3, k = 2;
Console.WriteLine(possibleWays(n, m, k));
}
}
JavaScript
// JavaScript program to find number of ways to
// make stable towers of given height.
function possibleWaysRecur(n, m, k) {
// Base cases:
// If height is 0, there is exactly 1 way (empty tower)
if (n === 0) return 1;
// If no more tile sizes are available,
// no ways can be formed
if (m === 0) return 0;
let ans = 0;
// Try using 'cnt' tiles of the current size
// (from 0 up to 'k' tiles) and make recursive
// calls for remaining height and tiles
for (let cnt = 0; cnt <= k && cnt <= n; cnt++) {
ans += possibleWaysRecur(n - cnt, m - 1, k);
}
return ans;
}
function possibleWays(n, m, k) {
return possibleWaysRecur(n, m, k);
}
const n = 3, m = 3, k = 2;
console.log(possibleWays(n, m, k));
Using Top-Down DP (Memoization) - O(n*m*k) Time and O(n*m) Space
If we notice carefully, we can observe that the above recursive solution holds the following two properties of Dynamic Programming.
1. Optimal Substructure: The solution to the tile stacking problem can be derived from the optimal solutions of smaller subproblems. Specifically, for any given n (height of tower) and m (sizes of tiles), we can express the recursive relation as follows:
- possibleWays(n, m, k) = sum of possibleWays(n - cnt, m - 1, k) for each cnt from 0 to min(k, n).
2. Overlapping Subproblems: When implementing a recursive approach to solve the tile stacking problem, we observe that many subproblems are computed multiple times.
- The recursive solution involves changing two parameters: n (height of tower) and the current tile size (m). We need to track both parameters, so we create a 2D array of size (n+1) x (m+1) because the value of n will be in the range [0, n] and m will be in the range [0, m+1].
- We initialize the 2D array with -1 to indicate that no subproblems have been computed yet.
- We check if the value at memo[n][m] is -1. If it is, we proceed to compute the result. otherwise, we return the stored result.
C++
// C++ program to find number of ways to
// make stable towers of given height.
#include <bits/stdc++.h>
using namespace std;
// Recursive function to calculate possible ways to
// form towers of height 'n' using tiles of sizes
// up to 'm' with at most 'k' tiles of each size
int possibleWaysRecur(int n, int m, int k,
vector<vector<int>> &memo) {
// Base cases:
// If height is 0, there is exactly 1 way (empty tower)
if (n == 0) return 1;
// If no more tile sizes are available,
// no ways can be formed
if (m == 0) return 0;
if (memo[n][m] != -1) return memo[n][m];
int ans = 0;
// Try using 'cnt' tiles of the current size
// (from 0 up to 'k' tiles) and make recursive
// calls for remaining height and tiles
for (int cnt = 0; cnt <= k && cnt <= n; cnt++) {
ans += possibleWaysRecur(n - cnt, m - 1, k, memo);
}
return memo[n][m] = ans;
}
int possibleWays(int n, int m, int k) {
vector<vector<int>> memo(n + 1, vector<int>(m + 1, -1));
return possibleWaysRecur(n, m, k, memo);
}
int main() {
int n = 3, m = 3, k = 2;
cout << possibleWays(n, m, k) << endl;
return 0;
}
Java
// Java program to find number of ways to
// make stable towers of given height.
class GfG {
static int possibleWaysRecur(int n, int m, int k, int[][] memo) {
// Base cases:
// If height is 0, there is exactly 1 way (empty tower)
if (n == 0) return 1;
// If no more tile sizes are available,
// no ways can be formed
if (m == 0) return 0;
if (memo[n][m] != -1) return memo[n][m];
int ans = 0;
// Try using 'cnt' tiles of the current size
// (from 0 up to 'k' tiles) and make recursive
// calls for remaining height and tiles
for (int cnt = 0; cnt <= k && cnt <= n; cnt++) {
ans += possibleWaysRecur(n - cnt, m - 1, k, memo);
}
return memo[n][m] = ans;
}
static int possibleWays(int n, int m, int k) {
int[][] memo = new int[n + 1][m + 1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= m; j++) {
memo[i][j] = -1;
}
}
return possibleWaysRecur(n, m, k, memo);
}
public static void main(String[] args) {
int n = 3, m = 3, k = 2;
System.out.println(possibleWays(n, m, k));
}
}
Python
# Python program to find number of ways to
# make stable towers of given height.
def possibleWaysRecur(n, m, k, memo):
# Base cases:
# If height is 0, there is exactly 1 way (empty tower)
if n == 0:
return 1
# If no more tile sizes are available,
# no ways can be formed
if m == 0:
return 0
if memo[n][m] != -1:
return memo[n][m]
ans = 0
# Try using 'cnt' tiles of the current size
# (from 0 up to 'k' tiles) and make recursive
# calls for remaining height and tiles
for cnt in range(min(k, n) + 1):
ans += possibleWaysRecur(n - cnt, m - 1, k, memo)
memo[n][m] = ans
return ans
def possibleWays(n, m, k):
memo = [[-1 for _ in range(m + 1)] for _ in range(n + 1)]
return possibleWaysRecur(n, m, k, memo)
if __name__ == "__main__":
n, m, k = 3, 3, 2
print(possibleWays(n, m, k))
C#
// C# program to find number of ways to
// make stable towers of given height.
using System;
class GfG {
static int possibleWaysRecur(int n, int m, int k, int[,] memo) {
// Base cases:
// If height is 0, there is exactly 1 way (empty tower)
if (n == 0) return 1;
// If no more tile sizes are available,
// no ways can be formed
if (m == 0) return 0;
if (memo[n, m] != -1) return memo[n, m];
int ans = 0;
// Try using 'cnt' tiles of the current size
// (from 0 up to 'k' tiles) and make recursive
// calls for remaining height and tiles
for (int cnt = 0; cnt <= k && cnt <= n; cnt++) {
ans += possibleWaysRecur(n - cnt, m - 1, k, memo);
}
memo[n, m] = ans;
return ans;
}
static int possibleWays(int n, int m, int k) {
int[,] memo = new int[n + 1, m + 1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= m; j++) {
memo[i, j] = -1;
}
}
return possibleWaysRecur(n, m, k, memo);
}
static void Main() {
int n = 3, m = 3, k = 2;
Console.WriteLine(possibleWays(n, m, k));
}
}
JavaScript
// JavaScript program to find number of ways to
// make stable towers of given height.
function possibleWaysRecur(n, m, k, memo) {
// Base cases:
// If height is 0, there is exactly 1 way (empty tower)
if (n === 0) return 1;
// If no more tile sizes are available,
// no ways can be formed
if (m === 0) return 0;
if (memo[n][m] !== -1) return memo[n][m];
let ans = 0;
// Try using 'cnt' tiles of the current size
// (from 0 up to 'k' tiles) and make recursive
// calls for remaining height and tiles
for (let cnt = 0; cnt <= k && cnt <= n; cnt++) {
ans += possibleWaysRecur(n - cnt, m - 1, k, memo);
}
memo[n][m] = ans;
return ans;
}
function possibleWays(n, m, k) {
let memo = Array.from({ length: n + 1 }, () => Array(m + 1).fill(-1));
return possibleWaysRecur(n, m, k, memo);
}
const n = 3, m = 3, k = 2;
console.log(possibleWays(n, m, k));
Using Bottom-Up DP (Tabulation) - O(n*m*k) Time and O(m*n) Space
The approach is similar to the previous one. Just instead of breaking down the problem recursively, we iteratively build up the solution by calculating in bottom-up manner.
The idea is to build the dp table where dp[i][j] represents the number of ways to form a tower of height i using tiles of sizes from 1 to j, with each tile being used at most k times.
The table is initialized with dp[0][j] = 1 for all j, as there is exactly one way to form a tower of height 0 (using no tiles). For each i (height) and j (tile size), the number of ways to form the tower is computed by first considering the ways without using the jth tile (dp[i][j] = dp[i][j-1]), and then adding the possibilities of using the jth tile from 1 to k times, provided the height i allows it (dp[i][j] += dp[i - cnt][j - 1] for each valid cnt).
C++
// C++ program to find number of ways to
// make stable towers of given height.
#include <bits/stdc++.h>
using namespace std;
// function to calculate possible ways to form
// towers of height 'n' using tiles of sizes up
// to 'm' with at most 'k' tiles of each size
int possibleWays(int n, int m, int k) {
vector<vector<int>> dp(n + 1, vector<int>(m + 1, 0));
// Base case for height 0
for (int j = 0; j <= m; j++) dp[0][j] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
// Not using the jth tile at all
dp[i][j] = dp[i][j - 1];
for (int cnt = 1; cnt <= k && cnt <= i; cnt++) {
dp[i][j] += dp[i - cnt][j - 1];
}
}
}
return dp[n][m];
}
int main() {
int n = 3, m = 3, k = 2;
cout << possibleWays(n, m, k) << endl;
return 0;
}
Java
// Java program to find number of ways to
// make stable towers of given height.
class GfG {
static int possibleWays(int n, int m, int k) {
int[][] dp = new int[n + 1][m + 1];
// Base case for height 0
for (int j = 0; j <= m; j++) dp[0][j] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
// Not using the jth tile at all
dp[i][j] = dp[i][j - 1];
for (int cnt = 1; cnt <= k && cnt <= i; cnt++) {
dp[i][j] += dp[i - cnt][j - 1];
}
}
}
return dp[n][m];
}
public static void main(String[] args) {
int n = 3, m = 3, k = 2;
System.out.println(possibleWays(n, m, k));
}
}
Python
# Python program to find number of ways to
# make stable towers of given height.
def possibleWays(n, m, k):
dp = [[0 for _ in range(m + 1)] for _ in range(n + 1)]
# Base case for height 0
for j in range(m + 1):
dp[0][j] = 1
for i in range(1, n + 1):
for j in range(1, m + 1):
# Not using the jth tile at all
dp[i][j] = dp[i][j - 1]
for cnt in range(1, min(k, i) + 1):
dp[i][j] += dp[i - cnt][j - 1]
return dp[n][m]
if __name__ == "__main__":
n, m, k = 3, 3, 2
print(possibleWays(n, m, k))
C#
// C# program to find number of ways to
// make stable towers of given height.
using System;
class GfG {
static int possibleWays(int n, int m, int k) {
int[,] dp = new int[n + 1, m + 1];
// Base case for height 0
for (int j = 0; j <= m; j++) dp[0, j] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
// Not using the jth tile at all
dp[i, j] = dp[i, j - 1];
for (int cnt = 1; cnt <= k && cnt <= i; cnt++) {
dp[i, j] += dp[i - cnt, j - 1];
}
}
}
return dp[n, m];
}
static void Main() {
int n = 3, m = 3, k = 2;
Console.WriteLine(possibleWays(n, m, k));
}
}
JavaScript
// JavaScript program to find number of ways to
// make stable towers of given height.
function possibleWays(n, m, k) {
let dp = Array.from({ length: n + 1 }, () => Array(m + 1).fill(0));
// Base case for height 0
for (let j = 0; j <= m; j++) dp[0][j] = 1;
for (let i = 1; i <= n; i++) {
for (let j = 1; j <= m; j++) {
// Not using the jth tile at all
dp[i][j] = dp[i][j - 1];
for (let cnt = 1; cnt <= k && cnt <= i; cnt++) {
dp[i][j] += dp[i - cnt][j - 1];
}
}
}
return dp[n][m];
}
const n = 3, m = 3, k = 2;
console.log(possibleWays(n, m, k));
Using Space Optimized DP - O(m*n*k) Time and O(n) Space
From the previous approach, we can observe that that value of dp[i][j] depends only on the previous row, ie, i-1. There is no need to store all the previous states just one previous state is used to compute result.
C++
// C++ program to find number of ways to
// make stable towers of given height.
#include <bits/stdc++.h>
using namespace std;
int possibleWays(int n, int m, int k) {
vector<int> curr(n + 1, 0), prev(n + 1, 0);
// Base case for height 0
prev[0] = 1;
for (int j = 1; j <= m; j++) {
// Base case for height 0 in the current row
curr[0] = 1;
for (int i = 1; i <= n; i++) {
curr[i] = prev[i];
for (int cnt = 1; cnt <= k && cnt <= i; cnt++) {
curr[i] += prev[i - cnt];
}
}
swap(curr, prev);
}
return prev[n];
}
int main() {
int n = 3, m = 3, k = 2;
cout << possibleWays(n, m, k) << endl;
return 0;
}
Java
// Java program to find number of ways to
// make stable towers of given height.
class GfG {
static int possibleWays(int n, int m, int k) {
int[] curr = new int[n + 1];
int[] prev = new int[n + 1];
// Base case for height 0
prev[0] = 1;
for (int j = 1; j <= m; j++) {
// Base case for height 0 in the current row
curr[0] = 1;
for (int i = 1; i <= n; i++) {
curr[i] = prev[i];
for (int cnt = 1; cnt <= k && cnt <= i; cnt++) {
curr[i] += prev[i - cnt];
}
}
// Swap curr and prev arrays
int[] temp = curr;
curr = prev;
prev = temp;
}
return prev[n];
}
public static void main(String[] args) {
int n = 3, m = 3, k = 2;
System.out.println(possibleWays(n, m, k));
}
}
Python
# Python program to find number of ways to
# make stable towers of given height.
def possibleWays(n, m, k):
curr = [0] * (n + 1)
prev = [0] * (n + 1)
# Base case for height 0
prev[0] = 1
for j in range(1, m + 1):
# Base case for height 0 in the current row
curr[0] = 1
for i in range(1, n + 1):
curr[i] = prev[i]
for cnt in range(1, min(k, i) + 1):
curr[i] += prev[i - cnt]
# Swap curr and prev arrays
prev, curr = curr, prev
return prev[n]
if __name__ == "__main__":
n, m, k = 3, 3, 2
print(possibleWays(n, m, k))
C#
// C# program to find number of ways to
// make stable towers of given height.
using System;
class GfG {
static int possibleWays(int n, int m, int k) {
int[] curr = new int[n + 1];
int[] prev = new int[n + 1];
// Base case for height 0
prev[0] = 1;
for (int j = 1; j <= m; j++) {
// Base case for height 0 in the current row
curr[0] = 1;
for (int i = 1; i <= n; i++) {
curr[i] = prev[i];
for (int cnt = 1; cnt <= k && cnt <= i; cnt++) {
curr[i] += prev[i - cnt];
}
}
// Swap curr and prev arrays
int[] temp = curr;
curr = prev;
prev = temp;
}
return prev[n];
}
static void Main() {
int n = 3, m = 3, k = 2;
Console.WriteLine(possibleWays(n, m, k));
}
}
JavaScript
// JavaScript program to find number of ways to
// make stable towers of given height.
function possibleWays(n, m, k) {
let curr = new Array(n + 1).fill(0);
let prev = new Array(n + 1).fill(0);
// Base case for height 0
prev[0] = 1;
for (let j = 1; j <= m; j++) {
// Base case for height 0 in the current row
curr[0] = 1;
for (let i = 1; i <= n; i++) {
curr[i] = prev[i];
for (let cnt = 1; cnt <= k && cnt <= i; cnt++) {
curr[i] += prev[i - cnt];
}
}
// Swap curr and prev arrays
[curr, prev] = [prev, curr];
}
return prev[n];
}
const n = 3, m = 3, k = 2;
console.log(possibleWays(n, m, k));
Similar Reads
Basics & Prerequisites
Data Structures
Array Data StructureIn this article, we introduce array, implementation in different popular languages, its basic operations and commonly seen problems / interview questions. An array stores items (in case of C/C++ and Java Primitive Arrays) or their references (in case of Python, JS, Java Non-Primitive) at contiguous
3 min read
String in Data StructureA string is a sequence of characters. The following facts make string an interesting data structure.Small set of elements. Unlike normal array, strings typically have smaller set of items. For example, lowercase English alphabet has only 26 characters. ASCII has only 256 characters.Strings are immut
2 min read
Hashing in Data StructureHashing is a technique used in data structures that efficiently stores and retrieves data in a way that allows for quick access. Hashing involves mapping data to a specific index in a hash table (an array of items) using a hash function. It enables fast retrieval of information based on its key. The
2 min read
Linked List Data StructureA linked list is a fundamental data structure in computer science. It mainly allows efficient insertion and deletion operations compared to arrays. Like arrays, it is also used to implement other data structures like stack, queue and deque. Hereâs the comparison of Linked List vs Arrays Linked List:
2 min read
Stack Data StructureA Stack is a linear data structure that follows a particular order in which the operations are performed. The order may be LIFO(Last In First Out) or FILO(First In Last Out). LIFO implies that the element that is inserted last, comes out first and FILO implies that the element that is inserted first
2 min read
Queue Data StructureA Queue Data Structure is a fundamental concept in computer science used for storing and managing data in a specific order. It follows the principle of "First in, First out" (FIFO), where the first element added to the queue is the first one to be removed. It is used as a buffer in computer systems
2 min read
Tree Data StructureTree Data Structure is a non-linear data structure in which a collection of elements known as nodes are connected to each other via edges such that there exists exactly one path between any two nodes. Types of TreeBinary Tree : Every node has at most two childrenTernary Tree : Every node has at most
4 min read
Graph Data StructureGraph Data Structure is a collection of nodes connected by edges. It's used to represent relationships between different entities. If you are looking for topic-wise list of problems on different topics like DFS, BFS, Topological Sort, Shortest Path, etc., please refer to Graph Algorithms. Basics of
3 min read
Trie Data StructureThe Trie data structure is a tree-like structure used for storing a dynamic set of strings. It allows for efficient retrieval and storage of keys, making it highly effective in handling large datasets. Trie supports operations such as insertion, search, deletion of keys, and prefix searches. In this
15+ min read
Algorithms
Searching AlgorithmsSearching algorithms are essential tools in computer science used to locate specific items within a collection of data. In this tutorial, we are mainly going to focus upon searching in an array. When we search an item in an array, there are two most common algorithms used based on the type of input
2 min read
Sorting AlgorithmsA Sorting Algorithm is used to rearrange a given array or list of elements in an order. For example, a given array [10, 20, 5, 2] becomes [2, 5, 10, 20] after sorting in increasing order and becomes [20, 10, 5, 2] after sorting in decreasing order. There exist different sorting algorithms for differ
3 min read
Introduction to RecursionThe process in which a function calls itself directly or indirectly is called recursion and the corresponding function is called a recursive function. A recursive algorithm takes one step toward solution and then recursively call itself to further move. The algorithm stops once we reach the solution
14 min read
Greedy AlgorithmsGreedy algorithms are a class of algorithms that make locally optimal choices at each step with the hope of finding a global optimum solution. At every step of the algorithm, we make a choice that looks the best at the moment. To make the choice, we sometimes sort the array so that we can always get
3 min read
Graph AlgorithmsGraph is a non-linear data structure like tree data structure. The limitation of tree is, it can only represent hierarchical data. For situations where nodes or vertices are randomly connected with each other other, we use Graph. Example situations where we use graph data structure are, a social net
3 min read
Dynamic Programming or DPDynamic Programming is an algorithmic technique with the following properties.It is mainly an optimization over plain recursion. Wherever we see a recursive solution that has repeated calls for the same inputs, we can optimize it using Dynamic Programming. The idea is to simply store the results of
3 min read
Bitwise AlgorithmsBitwise algorithms in Data Structures and Algorithms (DSA) involve manipulating individual bits of binary representations of numbers to perform operations efficiently. These algorithms utilize bitwise operators like AND, OR, XOR, NOT, Left Shift, and Right Shift.BasicsIntroduction to Bitwise Algorit
4 min read
Advanced
Segment TreeSegment Tree is a data structure that allows efficient querying and updating of intervals or segments of an array. It is particularly useful for problems involving range queries, such as finding the sum, minimum, maximum, or any other operation over a specific range of elements in an array. The tree
3 min read
Pattern SearchingPattern searching algorithms are essential tools in computer science and data processing. These algorithms are designed to efficiently find a particular pattern within a larger set of data. Patten SearchingImportant Pattern Searching Algorithms:Naive String Matching : A Simple Algorithm that works i
2 min read
GeometryGeometry is a branch of mathematics that studies the properties, measurements, and relationships of points, lines, angles, surfaces, and solids. From basic lines and angles to complex structures, it helps us understand the world around us.Geometry for Students and BeginnersThis section covers key br
2 min read
Interview Preparation
Practice Problem