Maximize non decreasing Array size by replacing Subarray with sum
Last Updated :
23 Jul, 2025
Given an array arr[] of size N. In one operation only one subarray can be selected and replaced with the sum of the subarray. The task is to find the maximum size of the array after making it non-decreasing.
Examples:
Input: N = 5, arr[] = {5, 1, 6, 6, 6}
Output: 4
Explanation: maximum size non-decreasing array, in this case, is {6, 6, 6, 6} which is obtained by replacing subarray(0, 1) = arr[0] + arr[1] = 6
Input: N = 9, arr[] = {5, 1, 6, 7, 7, 1, 6, 4, 5 }
Output: 6
Explanation: maximum size non-decreasing array, in this case, is {5, 7, 7, 7, 7, 9} which is obtained by replacing subarray(1, 2) = arr[1] + arr[2] = 7. Subarray(5, 6) = arr[5] + arr[6] = 7. Subarray(7, 8) = arr[7] + arr[8] = 9
[Naive Approach] Using Dynamic Programming (DP) - O(n^2) time and O(n) space
The idea behind this solution is to use dynamic programming to solve the problem, the main observation is that the maximum length of a non-decreasing array that can be created up to the current index i depends on the maximum length of a non-decreasing array that can be created up to a previous index j, where j < i. This is because the operation of replacing a subarray with its sum can only be performed on a contiguous subarray, and the resulting array must be non-decreasing.
By using dynamic programming, the solution can efficiently keep track of the maximum length of a non-decreasing array that can be created up to each index, and use this information to determine the maximum length that can be created up to the current index.
Below are the detailed steps of above intuition:
1. Initialize Arrays:
- prefix: Stores the cumulative sum of elements up to each index.
- dp: Stores the maximum length of the non-decreasing subarray that can be formed ending at each index.
- last: Stores the maximum subarray sum that ends at each index.
2. Calculate the prefix sum for each index.
3. Dynamic Programming Approach:
- Iterate through each index i starting from the second element.
- For each i, check all previous indices j to find the longest subarray that can be extended to include i.
- Update dp[i] and last[i] based on the conditions:
- If the current prefix sum prefix[i] is greater than or equal to the required sum last[j] + prefix[j], update dp[i] to dp[j] + 1 and set last[i] to prefix[i] - prefix[j]
4. Result: The value at dp[n - 1] will gives the length of the longest non-decreasing subarray that can be formed.
Code Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
// Function to find the maximum length of a non-decreasing
// array that can be made after applying operations
int findMaximumLength(vector<int>& nums)
{
int n = nums.size();
if (n == 0)
return 0;
// Prefix sum array to store cumulative sums
vector<long long> prefix(n), last(n), dp(n, 1);
// Initializing the prefix sum array
prefix[0] = nums[0];
for (int i = 1; i < n; i++) {
prefix[i] = prefix[i - 1] + nums[i];
}
// Initializing the last array
last[0] = nums[0];
// Dynamic Programming approach to find the maximum
// length
for (int i = 1; i < n; i++) {
bool found = false;
for (int j = i - 1; j >= 0; j--) {
// Check if current prefix sum is greater
// than or equal to the required sum
if (prefix[i] >= last[j] + prefix[j]) {
dp[i] = dp[j] + 1;
last[i] = prefix[i] - prefix[j];
found = true;
break;
}
}
// If no valid subarray is found, set last[i] to
// prefix[i]
if (!found)
last[i] = prefix[i];
}
// The result is the dp[n - 1] value in dp array
return dp[n - 1];
}
int main()
{
// Test case 1
vector<int> nums1 = { 5, 1, 6, 6, 6 };
cout << findMaximumLength(nums1) << endl;
// Test case 2
vector<int> nums2 = { 5, 1, 6, 7, 7, 1, 6, 4, 5 };
cout << findMaximumLength(nums2) << endl;
return 0;
}
Java
import java.util.*;
public class Main {
// Function to find the maximum length of a
// non-decreasing array that can be made after applying
// operations
public static int findMaximumLength(List<Integer> nums)
{
int n = nums.size(); // Length of the input list
// If the list is empty, return 0 as there is no
// array to process
if (n == 0)
return 0;
// Arrays to store prefix sums, the last element of
// the longest subarray ending at each position, and
// DP values
long[] prefix = new long[n];
long[] last = new long[n];
int[] dp = new int[n];
// Initializing the dp array with 1 since each
// element is at least a subarray of length 1
Arrays.fill(dp, 1);
// Initializing the prefix sum array
prefix[0] = nums.get(0);
for (int i = 1; i < n; i++) {
prefix[i] = prefix[i - 1] + nums.get(i);
}
// Initializing the last array with the first
// element
last[0] = nums.get(0);
// Dynamic Programming approach to find the maximum
// length
for (int i = 1; i < n; i++) {
// Flag to check if a valid subarray ending at i
// is found
boolean found = false;
// Check all previous elements to find the
// longest valid subarray ending at i
for (int j = i - 1; j >= 0; j--) {
// If the current prefix sum is greater than
// or equal to the required sum
if (prefix[i] >= last[j] + prefix[j]) {
// Update dp value for the current
// position
dp[i] = dp[j] + 1;
// Update the last element of the
// longest subarray ending at i
last[i] = prefix[i] - prefix[j];
// Set the flag as true since a valid
// subarray is found
found = true;
// Exit the loop as we found the longest
// valid subarray ending at i
break;
}
}
// If no valid subarray is found, set last[i] to
// prefix[i]
if (!found)
last[i] = prefix[i];
}
// The result is the dp[n - 1] value in dp array,
// which contains the maximum length
return dp[n - 1];
}
// Driver Code
public static void main(String[] args)
{
// Test case 1
List<Integer> nums1 = Arrays.asList(5, 1, 6, 6, 6);
System.out.println(
findMaximumLength(nums1));
// Test case 2
List<Integer> nums2
= Arrays.asList(5, 1, 6, 7, 7, 1, 6, 4, 5);
System.out.println(
findMaximumLength(nums2));
}
}
Python
def find_maximum_length(nums):
n = len(nums) # Length of the input list
if n == 0:
return 0 # If the list is empty, return 0 as there is no array to process
# Prefix sum array to store cumulative sums
prefix = [0] * n
last = [0] * n
# Initializing the dp array with 1 since each element
# is at least a subarray of length 1
dp = [1] * n
# Initializing the prefix sum array
prefix[0] = nums[0]
for i in range(1, n):
prefix[i] = prefix[i - 1] + nums[i]
# Initializing the last array with the first element
last[0] = nums[0]
# Dynamic Programming approach to find the maximum length
for i in range(1, n):
# Flag to check if a valid subarray ending at i is found
found = False
# Check all previous elements to find the longest valid
# subarray ending at i
for j in range(i - 1, -1, -1):
# If the current prefix sum is greater than or equal
# to the required sum
if prefix[i] >= last[j] + prefix[j]:
# Update dp value for the current position
dp[i] = dp[j] + 1
# Update the last element of the longest subarray
# ending at i
last[i] = prefix[i] - prefix[j]
# Set the flag as true since a valid subarray is found
found = True
# Exit the loop as we found the longest valid
# subarray ending at i
break
# If no valid subarray is found, set last[i] to prefix[i]
if not found:
last[i] = prefix[i]
# The result is the dp[n - 1] value in dp array, which
# contains the maximum length
return dp[n - 1]
# Driver Code
if __name__ == "__main__":
# Test case 1
nums1 = [5, 1, 6, 6, 6]
print(find_maximum_length(nums1))
# Test case 2
nums2 = [5, 1, 6, 7, 7, 1, 6, 4, 5]
print(find_maximum_length(nums2))
C#
using System;
using System.Collections.Generic;
public class Program {
// Function to find the maximum length of a
// non-decreasing array that can be made after applying
// operations
public static int FindMaximumLength(List<int> nums)
{
int n = nums.Count; // Length of the input list
// If the list is empty, return 0 as there is no
// array to process
if (n == 0)
return 0;
// Arrays to store prefix sums, the last element of
// the longest subarray ending at each position, and
// DP values
long[] prefix = new long[n];
long[] last = new long[n];
int[] dp = new int[n];
// Initializing the dp array with 1 since each
// element is at least a subarray of length 1
Array.Fill(dp, 1);
// Initializing the prefix sum array
prefix[0] = nums[0];
for (int i = 1; i < n; i++) {
prefix[i] = prefix[i - 1] + nums[i];
}
// Initializing the last array with the first
// element
last[0] = nums[0];
// Dynamic Programming approach to find the maximum
// length
for (int i = 1; i < n; i++) {
// Flag to check if a valid subarray ending at i
// is found
bool found = false;
// Check all previous elements to find the
// longest valid subarray ending at i
for (int j = i - 1; j >= 0; j--) {
// If the current prefix sum is greater than
// or equal to the required sum
if (prefix[i] >= last[j] + prefix[j]) {
// Update dp value for the current
// position
dp[i] = dp[j] + 1;
// Update the last element of the
// longest subarray ending at i
last[i] = prefix[i] - prefix[j];
// Set the flag as true since a valid
// subarray is found
found = true;
// Exit the loop as we found the longest
// valid subarray ending at i
break;
}
}
// If no valid subarray is found, set last[i] to
// prefix[i]
if (!found)
last[i] = prefix[i];
}
// The result is the dp[n - 1] value in dp array,
// which contains the maximum length
return dp[n - 1];
}
// Driver Code
public static void Main()
{
// Test case 1
List<int> nums1 = new List<int>{ 5, 1, 6, 6, 6 };
Console.WriteLine(FindMaximumLength(nums1));
// Test case 2
List<int> nums2
= new List<int>{ 5, 1, 6, 7, 7, 1, 6, 4, 5 };
Console.WriteLine(FindMaximumLength(nums2));
}
}
JavaScript
// Function to find the maximum length of a non-decreasing array
// that can be made after applying operations
function findMaximumLength(nums) {
// Length of the input array
const n = nums.length;
// If the array is empty, return 0 as there is
// no array to process
if (n === 0)
return 0;
// Arrays to store prefix sums, the last element
// of the longest subarray ending at each position,
// and DP values
const prefix = new Array(n).fill(0);
const last = new Array(n).fill(0);
// Initializing the dp array with 1 since each
// element is at least a subarray of length 1
const dp = new Array(n).fill(1);
// Initializing the prefix sum array
prefix[0] = nums[0];
for (let i = 1; i < n; i++) {
prefix[i] = prefix[i - 1] + nums[i];
}
// Initializing the last array with the first element
last[0] = nums[0];
// Dynamic Programming approach to find the
// maximum length
for (let i = 1; i < n; i++) {
// Flag to check if a valid subarray ending
// at i is found
let found = false;
// Check all previous elements to find the
// longest valid subarray ending at i
for (let j = i - 1; j >= 0; j--) {
// If the current prefix sum is greater
// than or equal to the required sum
if (prefix[i] >= last[j] + prefix[j]) {
// Update dp value for the current position
dp[i] = dp[j] + 1;
// Update the last element of the longest
// subarray ending at i
last[i] = prefix[i] - prefix[j];
// Set the flag as true since a valid
// subarray is found
found = true;
// Exit the loop as we found the longest
// valid subarray ending at i
break;
}
}
// If no valid subarray is found, set last[i] to prefix[i]
if (!found)
last[i] = prefix[i];
}
// The result is the dp[n - 1] value in dp array,
// which contains the maximum length
return dp[n - 1];
}
// Driver Code
// Test case 1
const nums1 = [5, 1, 6, 6, 6];
console.log(findMaximumLength(nums1));
// Test case 2
const nums2 = [5, 1, 6, 7, 7, 1, 6, 4, 5];
console.log(findMaximumLength(nums2));
Time Complexity: O(n2)
Auxiliary Space: O(n)
[Expected Approach] Using DP + Binary Search + Monotonic Stack - O(n log(n)) time and O(n) space
The problem is all about, we need to divide the array into subarrays such that replacing each subarray with its sum results in a non-decreasing array. At any index i, we need to determine the maximum number of subarrays that can be formed from the start up to i while maintaining the non-decreasing property.
We always have a minimum answer of 1 at any index (from 0 to i). We need to look how can we maximize our answer for ith index. Maximizing our answer for each index gives us a hint that our answer for ith index will always be >= (i-1)th index, as if answer for ith index comes to be smaller than (i-1)th index, we can always add ith element to subarray which has (i-1)th element and get our answer for ith index = answer for (i-1)th index.
Lets look at our dp states and transititons:
Create a dp array, where dp[i] as the best answer for the subarray ending at index i.
To find dp[i], we need to look for an index j (where 0 <= j < i) such that the sum of the subarray from j+1 to i is greater than or equal to the sum of the subarray that includes arr[j] (let's call this last[j]). This can be represented as
- prefixsum[i] - prefixsum[j] ≥ sumlast[j]
- prefixsum[i] ≥ sumlast[j] + prefixsum[j]
Here, last[i] is defined as prefixsum[i] - prefixsum[j]. For each index i, any index j satisfying the above condition can be considered for calculating dp[i]. Thus: dp[i] = max(dp[j]+1) for all 0 ≤ j < i. We will look for bigger value to j to maximise the result at dp[j].
Below are the detailed steps of above intuition:
- Calculate the prefix sums of the array.
- Initialize a vector stk where each element is a pair consisting of (prefix[index] + sumlast[index], index).
- For every index i, perform a binary search to find the index j such that (sumlast[j] + prefixsum[j] <= prefixsum[i]) and is closest to i.
- Update dp[i] = dp[j] + 1.
- Maintain the monotonic stack property by removing elements that do not satisfy the condition because this will help use to do binary search on monotonic stack.
Code Implementation:
C++
#include <bits/stdc++.h>
using namespace std;
// Function to find the maximum length of a non-decreasing
// array that can be made after applying operations
int findMaximumLength(vector<int>& arr)
{
// Length of the input array
int n = arr.size();
// prefixSum stores the prefix sums of the arr array
vector<long long> prefixSum(n + 1, 0);
// dp stores the maximum length of a non-decreasing
// subarray ending at each index
vector<int> dp(n + 1, 0);
// Calculate prefix sums
for (int i = 1; i <= n; i++)
prefixSum[i] = prefixSum[i - 1] + arr[i - 1];
// stk stores pairs of {value, index} to maintain
// potential maximum lengths
vector<vector<long long> > stk;
stk.push_back({ 0, 0 });
// Iterate over the array to find the maximum length
for (int i = 1; i <= n; i++) {
int low = 0, high = stk.size() - 1;
int j = 0;
// Binary search to find the largest j such that
// prefixSum[j] <= prefixSum[i]
while (low <= high) {
int mid = low + (high - low) / 2;
if (stk[mid][0] <= prefixSum[i]) {
j = max(j, mid);
low = mid + 1;
}
else {
high = mid - 1;
}
}
// Index of the largest valid prefix sum
int index = stk[j][1];
// Update dp[i] to reflect the maximum length of
// non-decreasing subarray ending at i
dp[i] = dp[index] + 1;
// Calculate the new value to be added to stk
long long currLast
= 2 * prefixSum[i] - prefixSum[index];
// Maintain the stack property by removing elements
// that do not satisfy the condition
while (stk.back()[0] >= currLast)
stk.pop_back();
// Add the new value and index to stk
stk.push_back({ currLast, i });
}
// The result is the maximum length of non-decreasing
// subarray that can be obtained
return dp[n];
}
// Driver code to test the above function
int main()
{
// Test case 1
vector<int> nums1 = { 5, 1, 6, 6, 6 };
cout << findMaximumLength(nums1) << endl;
// Test case 2
vector<int> nums2 = { 5, 1, 6, 7, 7, 1, 6, 4, 5 };
cout << findMaximumLength(nums2) << endl;
return 0;
}
Java
import java.util.*;
public class Main {
// Function to find the maximum length of a
// non-decreasing array that can be made after applying
// operations
public static int findMaximumLength(List<Integer> arr)
{
// Length of the input array
int n = arr.size();
// prefixSum stores the prefix sums of the arr array
long[] prefixSum = new long[n + 1];
// dp stores the maximum length of a non-decreasing
// subarray ending at each index
int[] dp = new int[n + 1];
// Calculate prefix sums
for (int i = 1; i <= n; i++)
prefixSum[i]
= prefixSum[i - 1] + arr.get(i - 1);
// stk stores pairs of {value, index} to maintain
// potential maximum lengths
List<long[]> stk = new ArrayList<>();
stk.add(new long[] { 0, 0 });
// Iterate over the array to find the maximum length
for (int i = 1; i <= n; i++) {
int low = 0, high = stk.size() - 1;
int j = 0;
// Binary search to find the largest j such that
// prefixSum[j] <= prefixSum[i]
while (low <= high) {
int mid = low + (high - low) / 2;
if (stk.get(mid)[0] <= prefixSum[i]) {
j = Math.max(j, mid);
low = mid + 1;
}
else {
high = mid - 1;
}
}
// Index of the largest valid prefix sum
int index = (int)stk.get(j)[1];
// Update dp[i] to reflect the maximum length of
// non-decreasing subarray ending at i
dp[i] = dp[index] + 1;
// Calculate the new value to be added to stk
long currLast
= 2 * prefixSum[i] - prefixSum[index];
// Maintain the stack property by removing
// elements that do not satisfy the condition
while (stk.get(stk.size() - 1)[0] >= currLast)
stk.remove(stk.size() - 1);
// Add the new value and index to stk
stk.add(new long[] { currLast, i });
}
// The result is the maximum length of
// non-decreasing subarray that can be obtained
return dp[n];
}
// Driver code to test the above function
public static void main(String[] args)
{
// Test case 1
List<Integer> nums1 = Arrays.asList(5, 1, 6, 6, 6);
System.out.println(
findMaximumLength(nums1)); // Expected output
// Test case 2
List<Integer> nums2
= Arrays.asList(5, 1, 6, 7, 7, 1, 6, 4, 5);
System.out.println(
findMaximumLength(nums2)); // Expected output
}
}
Python
def find_maximum_length(arr):
# Length of the input array
n = len(arr)
# prefixSum stores the prefix sums of the arr array
prefixSum = [0] * (n + 1)
# dp stores the maximum length of a non-decreasing
# subarray ending at each index
dp = [0] * (n + 1)
# Calculate prefix sums
for i in range(1, n + 1):
prefixSum[i] = prefixSum[i - 1] + arr[i - 1]
# stk stores pairs of {value, index} to maintain
# potential maximum lengths
stk = [[0, 0]]
# Iterate over the array to find the maximum length
for i in range(1, n + 1):
low, high = 0, len(stk) - 1
j = 0
# Binary search to find the largest j such that
# prefixSum[j] <= prefixSum[i]
while low <= high:
mid = low + (high - low) // 2
if stk[mid][0] <= prefixSum[i]:
j = max(j, mid)
low = mid + 1
else:
high = mid - 1
# Index of the largest valid prefix sum
index = stk[j][1]
# Update dp[i] to reflect the maximum length of
# non-decreasing subarray ending at i
dp[i] = dp[index] + 1
# Calculate the new value to be added to stk
currLast = 2 * prefixSum[i] - prefixSum[index]
# Maintain the stack property by removing elements
# that do not satisfy the condition
while stk[-1][0] >= currLast:
stk.pop()
# Add the new value and index to stk
stk.append([currLast, i])
# The result is the maximum length of non-decreasing
# subarray that can be obtained
return dp[n]
# Driver code to test the above function
if __name__ == "__main__":
# Test case 1
nums1 = [5, 1, 6, 6, 6]
print(find_maximum_length(nums1))
# Test case 2
nums2 = [5, 1, 6, 7, 7, 1, 6, 4, 5]
print(find_maximum_length(nums2))
C#
using System;
using System.Collections.Generic;
public class Program {
// Function to find the maximum length of a
// non-decreasing array that can be made after applying
// operations
public static int FindMaximumLength(List<int> arr)
{
// Length of the input array
int n = arr.Count;
// prefixSum stores the prefix sums of the arr array
long[] prefixSum = new long[n + 1];
// dp stores the maximum length of a non-decreasing
// subarray ending at each index
int[] dp = new int[n + 1];
// Calculate prefix sums
for (int i = 1; i <= n; i++)
prefixSum[i] = prefixSum[i - 1] + arr[i - 1];
// stk stores pairs of {value, index} to maintain
// potential maximum lengths
List<long[]> stk = new List<long[]>();
stk.Add(new long[] { 0, 0 });
// Iterate over the array to find the maximum length
for (int i = 1; i <= n; i++) {
int low = 0, high = stk.Count - 1;
int j = 0;
// Binary search to find the largest j such that
// prefixSum[j] <= prefixSum[i]
while (low <= high) {
int mid = low + (high - low) / 2;
if (stk[mid][0] <= prefixSum[i]) {
j = Math.Max(j, mid);
low = mid + 1;
}
else {
high = mid - 1;
}
}
// Index of the largest valid prefix sum
int index = (int)stk[j][1];
// Update dp[i] to reflect the maximum length of
// non-decreasing subarray ending at i
dp[i] = dp[index] + 1;
// Calculate the new value to be added to stk
long currLast
= 2 * prefixSum[i] - prefixSum[index];
// Maintain the stack property by removing
// elements that do not satisfy the condition
while (stk[stk.Count - 1][0] >= currLast)
stk.RemoveAt(stk.Count - 1);
// Add the new value and index to stk
stk.Add(new long[] { currLast, i });
}
// The result is the maximum length of
// non-decreasing subarray that can be obtained
return dp[n];
}
// Driver code to test the above function
public static void Main()
{
// Test case 1
List<int> nums1 = new List<int>{ 5, 1, 6, 6, 6 };
Console.WriteLine(FindMaximumLength(nums1));
// Test case 2
List<int> nums2
= new List<int>{ 5, 1, 6, 7, 7, 1, 6, 4, 5 };
Console.WriteLine(FindMaximumLength(nums2));
}
}
JavaScript
// Function to find the maximum length of a non-decreasing
// array that can be made after applying operations
function findMaximumLength(arr) {
// Length of the input array
const n = arr.length;
// prefixSum stores the prefix sums of the arr array
const prefixSum = new Array(n + 1).fill(0);
// dp stores the maximum length of a non-decreasing
// subarray ending at each index
const dp = new Array(n + 1).fill(0);
// Calculate prefix sums
for (let i = 1; i <= n; i++)
prefixSum[i] = prefixSum[i - 1] + arr[i - 1];
// stk stores pairs of {value, index} to maintain
// potential maximum lengths
const stk = [[0, 0]];
// Iterate over the array to find the maximum length
for (let i = 1; i <= n; i++) {
let low = 0, high = stk.length - 1;
let j = 0;
// Binary search to find the largest j such that
// prefixSum[j] <= prefixSum[i]
while (low <= high) {
const mid = low + Math.floor((high - low) / 2);
if (stk[mid][0] <= prefixSum[i]) {
j = Math.max(j, mid);
low = mid + 1;
} else {
high = mid - 1;
}
}
// Index of the largest valid prefix sum
const index = stk[j][1];
// Update dp[i] to reflect the maximum length of
// non-decreasing subarray ending at i
dp[i] = dp[index] + 1;
// Calculate the new value to be added to stk
const currLast = 2 * prefixSum[i] - prefixSum[index];
// Maintain the stack property by removing elements
// that do not satisfy the condition
while (stk[stk.length - 1][0] >= currLast)
stk.pop();
// Add the new value and index to stk
stk.push([currLast, i]);
}
// The result is the maximum length of non-decreasing
// subarray that can be obtained
return dp[n];
}
// Driver code to test the above function
// Test case 1
const nums1 = [5, 1, 6, 6, 6];
console.log(findMaximumLength(nums1));
// Test case 2
const nums2 = [5, 1, 6, 7, 7, 1, 6, 4, 5];
console.log(findMaximumLength(nums2)); // Expected output
Time Complexity: O(n*log(n))
Auxiliary Space: O(n)
Similar Reads
Basics & Prerequisites
Data Structures
Getting Started with Array Data StructureArray is a collection of items of the same variable type that are stored at contiguous memory locations. It is one of the most popular and simple data structures used in programming. Basic terminologies of ArrayArray Index: In an array, elements are identified by their indexes. Array index starts fr
14 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