Count all Grandparent-Parent-Child Triplets in a binary tree whose sum is greater than X
Last Updated :
22 Mar, 2023
Given an integer X and a binary tree, the task is to count the number of triplet triplets of nodes such that their sum is greater than X and they have a grandparent -> parent -> child relationship.

Example:
Input: X = 100
10
/ \
1 22
/ \ / \
35 4 15 67
/ \ / \ / \ / \
57 38 9 10 110 312 131 414
/ \
8 39
Output: 6
The triplets are:
22 -> 15 -> 110
22 -> 15 -> 312
15 -> 312 -> 8
22 -> 67 -> 131
22 -> 67 -> 414
67 -> 414 -> 39
Approach: The problem can be solved using a rolling sum up approach with a rolling period as 3 (grandparent -> parent -> child)
- Traverse the tree in preorder or postorder (INORDER WON’T WORK)
- Maintain a stack where we maintain rolling sum with a rolling period as 3
- Whenever we have more than 3 elements in the stack and if the topmost value is greater than X, we increment the result by 1.
- When we move up the recursion tree we do a POP operation on the stack so that all the rolling sums of lower levels get removed from the stack.
Below is the implementation of the above approach:
C++
#include <iostream>
#include <vector>
using namespace std;
// Class to store node information
class Node {
public:
int val;
Node* left;
Node* right;
Node(int value = 0, Node* l = nullptr,
Node* r = nullptr)
: val(value)
, left(l)
, right(r)
{
}
};
// Stack to perform stack operations
class Stack {
public:
vector<int> stack;
int size() { return stack.size(); }
int top()
{
return (size() > 0) ? stack[size() - 1] : 0;
}
void push(int val) { stack.push_back(val); }
void pop()
{
if (size() >= 1) {
stack.pop_back();
}
else {
stack.clear();
}
}
// Period is 3 to satisfy grandparent-parent-child
// relationship
void rolling_push(int val, int period = 3)
{
// Find the index of element to remove
int to_remove_idx = size() - period;
// If index is out of bounds then we remove nothing,
// i.e, 0
int to_remove = (to_remove_idx < 0)
? 0
: stack[to_remove_idx];
// For rolling sum what we want is that at each
// index i, we remove out-of-period elements, but
// since we are not maintaining a separate list of
// actual elements, we can get the actual element by
// taking diff between current and previous element.
// So every time we remove an element, we also add
// the element just before it, which is equivalent
// to removing the actual value and not the rolling
// sum.
// If index is out of bounds or 0 then we add
// nothing i.e, 0, because there is no previous
// element
int to_add = (to_remove_idx <= 0)
? 0
: stack[to_remove_idx - 1];
// If stack is empty then just push the value
// Else add last element to current value to get
// rolling sum then subtract out-of-period elements,
// then finally add the element just before
// out-of-period element
if (size() <= 0) {
push(val);
}
else {
push(val + stack[size() - 1] - to_remove
+ to_add);
}
}
void show()
{
for (auto item : stack) {
cout << item << " ";
}
cout << endl;
}
};
// Global variables used by count_with_greater_sum()
int count = 0;
Stack s;
void count_with_greater_sum(Node* root_node, int x)
{
if (!root_node) {
return;
}
s.rolling_push(root_node->val);
if (s.size() >= 3 && s.top() > x) {
count++;
}
count_with_greater_sum(root_node->left, x);
count_with_greater_sum(root_node->right, x);
// Moving up the tree so pop the last element
s.pop();
}
int main()
{
Node* root = new Node(10);
root->left = new Node(1);
root->right = new Node(22);
root->left->left = new Node(35);
root->left->right = new Node(4);
root->right->left = new Node(15);
root->right->right = new Node(67);
root->left->left->left = new Node(57);
root->left->left->right = new Node(38);
root->left->right->left = new Node(9);
root->left->right->right = new Node(10);
root->right->left->left = new Node(110);
root->right->left->right = new Node(312);
root->right->right->left = new Node(131);
root->right->right->right = new Node(414);
root->right->left->right->left = new Node(8);
root->right->right->right->right = new Node(39);
count_with_greater_sum(root, 100);
cout << count << endl;
}
Python3
# Python3 implementation of the approach
# Class to store node information
class Node:
def __init__(self, val = None, left = None, right = None):
self.val = val
self.left = left
self.right = right
# Stack to perform stack operations
class Stack:
def __init__(self):
self.stack = []
@property
def size(self):
return len(self.stack)
def top(self):
return self.stack[self.size - 1] if self.size > 0 else 0
def push(self, val):
self.stack.append(val)
def pop(self):
if self.size >= 1:
self.stack.pop(self.size - 1)
else:
self.stack = []
# Period is 3 to satisfy grandparent-parent-child relationship
def rolling_push(self, val, period = 3):
# Find the index of element to remove
to_remove_idx = self.size - period
# If index is out of bounds then we remove nothing, i.e, 0
to_remove = 0 if to_remove_idx < 0 else self.stack[to_remove_idx]
# For rolling sum what we want is that at each index i,
# we remove out-of-period elements, but since we are not
# maintaining a separate list of actual elements,
# we can get the actual element by taking diff between current
# and previous element. So every time we remove an element,
# we also add the element just before it, which is
# equivalent to removing the actual value and not the rolling sum.
# If index is out of bounds or 0 then we add nothing
# i.e, 0, because there is no previous element
to_add = 0 if to_remove_idx <= 0 else self.stack[to_remove_idx - 1]
# If stack is empty then just push the value
# Else add last element to current value to get rolling sum
# then subtract out-of-period elements,
# then finally add the element just before out-of-period element
self.push(val if self.size <= 0 else val + self.stack[self.size - 1]
- to_remove + to_add)
def show(self):
for item in self.stack:
print(item)
# Global variables used by count_with_greater_sum()
count = 0
s = Stack()
def count_with_greater_sum(root_node, x):
global s, count
if not root_node:
return 0
s.rolling_push(root_node.val)
if s.size >= 3 and s.top() > x:
count += 1
count_with_greater_sum(root_node.left, x)
count_with_greater_sum(root_node.right, x)
# Moving up the tree so pop the last element
s.pop()
if __name__ == '__main__':
root = Node(10)
root.left = Node(1)
root.right = Node(22)
root.left.left = Node(35)
root.left.right = Node(4)
root.right.left = Node(15)
root.right.right = Node(67)
root.left.left.left = Node(57)
root.left.left.right = Node(38)
root.left.right.left = Node(9)
root.left.right.right = Node(10)
root.right.left.left = Node(110)
root.right.left.right = Node(312)
root.right.right.left = Node(131)
root.right.right.right = Node(414)
root.right.left.right.left = Node(8)
root.right.right.right.right = Node(39)
count_with_greater_sum(root, 100)
print(count)
JavaScript
// Class to store node information
class Node {
constructor(val = null, left = null, right = null) {
this.val = val;
this.left = left;
this.right = right;
}
}
// Stack to perform stack operations
class Stack {
constructor() {
this.stack = [];
}
get size() {
return this.stack.length;
}
top() {
return this.size > 0 ? this.stack[this.size - 1] : 0;
}
push(val) {
this.stack.push(val);
}
pop() {
if (this.size >= 1) {
this.stack.pop();
} else {
this.stack = [];
}
}
// Period is 3 to satisfy grandparent-parent-child relationship
rolling_push(val, period = 3) {
// Find the index of element to remove
const to_remove_idx = this.size - period;
// If index is out of bounds then we remove nothing, i.e, 0
const to_remove = to_remove_idx < 0 ? 0 : this.stack[to_remove_idx];
// For rolling sum what we want is that at each index i,
// we remove out-of-period elements, but since we are not
// maintaining a separate list of actual elements,
// we can get the actual element by taking diff between current
// and previous element. So every time we remove an element,
// we also add the element just before it, which is
// equivalent to removing the actual value and not the rolling sum.
// If index is out of bounds or 0 then we add nothing
// i.e, 0, because there is no previous element
const to_add = to_remove_idx <= 0 ? 0 : this.stack[to_remove_idx - 1];
// If stack is empty then just push the value
// Else add last element to current value to get rolling sum
// then subtract out-of-period elements,
// then finally add the element just before out-of-period element
this.push(
val +
(this.size <= 0 ? 0 : this.stack[this.size - 1]) -
to_remove +
to_add
);
}
show() {
for (const item of this.stack) {
console.log(item);
}
}
}
// Global variables used by count_with_greater_sum()
let count = 0;
const s = new Stack();
function count_with_greater_sum(root_node, x) {
if (!root_node) {
return 0;
}
s.rolling_push(root_node.val);
if (s.size >= 3 && s.top() > x) {
count += 1;
}
count_with_greater_sum(root_node.left, x);
count_with_greater_sum(root_node.right, x);
// Moving up the tree so pop the last element
s.pop();
}
const root = new Node(10);
root.left = new Node(1);
root.right = new Node(22);
root.left.left = new Node(35);
root.left.right = new Node(4);
root.right.left = new Node(15);
root.right.right = new Node(67);
root.left.left.left = new Node(57);
root.left.left.right = new Node(38);
root.left.right.left = new Node(9);
root.left.right.right = new Node(10);
root.right.left.left = new Node(110);
root.right.left.right = new Node(312);
root.right.right.left = new Node(131);
root.right.right.right = new Node(414);
root.right.left.right.left = new Node(8);
root.right.right.right.right = new Node(39);
count_with_greater_sum(root, 100);
console.log(count);
// This code is contributed by Prince
Java
import java.util.*;
class Node {
int val;
Node left;
Node right;
Node(int value, Node l, Node r)
{
val = value;
left = l;
right = r;
}
Node(int value) { this(value, null, null); }
}
class Stack {
ArrayList<Integer> stack = new ArrayList<>();
int size() { return stack.size(); }
int top()
{
return (size() > 0) ? stack.get(size() - 1) : 0;
}
void push(int val) { stack.add(val); }
void pop()
{
if (size() >= 1) {
stack.remove(size() - 1);
}
else {
stack.clear();
}
}
void rolling_push(int val, int period)
{
int to_remove_idx = size() - period;
int to_remove = (to_remove_idx < 0)
? 0
: stack.get(to_remove_idx);
int to_add = (to_remove_idx <= 0)
? 0
: stack.get(to_remove_idx - 1);
if (size() <= 0) {
push(val);
}
else {
push(val + stack.get(size() - 1) - to_remove
+ to_add);
}
}
void show()
{
for (int item : stack) {
System.out.print(item + " ");
}
System.out.println();
}
}
public class Main {
static int count = 0;
static Stack s = new Stack();
static void count_with_greater_sum(Node root_node,
int x)
{
if (root_node == null) {
return;
}
s.rolling_push(root_node.val, 3);
if (s.size() >= 3 && s.top() > x) {
count++;
}
count_with_greater_sum(root_node.left, x);
count_with_greater_sum(root_node.right, x);
s.pop();
}
public static void main(String[] args)
{
Node root = new Node(10);
root.left = new Node(1);
root.right = new Node(22);
root.left.left = new Node(35);
root.left.right = new Node(4);
root.right.left = new Node(15);
root.right.right = new Node(67);
root.left.left.left = new Node(57);
root.left.left.right = new Node(38);
root.left.right.left = new Node(9);
root.left.right.right = new Node(10);
root.right.left.left = new Node(110);
root.right.left.right = new Node(312);
root.right.right.left = new Node(131);
root.right.right.right = new Node(414);
root.right.left.right.left = new Node(8);
root.right.right.right.right = new Node(39);
count_with_greater_sum(root, 100);
System.out.println(count);
}
}
C#
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
// C# code addition
class Node {
public int val;
public Node left;
public Node right;
public Node(int value, Node l, Node r)
{
val = value;
left = l;
right = r;
}
public Node(int value){
val = value;
left = null;
right = null;
}
}
class stack {
public List<int> st = new List<int>();
public int size() { return st.Count; }
public int top()
{
return (size() > 0) ? st[size() - 1]: 0;
}
public void push(int val) { st.Add(val); }
public void pop()
{
if (size() >= 1) {
st.RemoveAt(size() - 1);
}
else {
st.Clear();
}
}
public void rolling_push(int val, int period)
{
int to_remove_idx = size() - period;
int to_remove = (to_remove_idx < 0)
? 0
: st[to_remove_idx];
int to_add = (to_remove_idx <= 0)
? 0
: st[to_remove_idx - 1];
if (size() <= 0) {
push(val);
}
else {
push(val + st[size() - 1]- to_remove
+ to_add);
}
}
public void show()
{
foreach(var item in st){
Console.Write(item + " ");
}
Console.WriteLine();
}
}
public class HelloWorld {
static int count = 0;
static stack s = new stack();
static void count_with_greater_sum(Node root_node,
int x)
{
if (root_node == null) {
return;
}
s.rolling_push(root_node.val, 3);
if (s.size() >= 3 && s.top() > x) {
count++;
}
count_with_greater_sum(root_node.left, x);
count_with_greater_sum(root_node.right, x);
s.pop();
}
static void Main() {
Node root = new Node(10);
root.left = new Node(1);
root.right = new Node(22);
root.left.left = new Node(35);
root.left.right = new Node(4);
root.right.left = new Node(15);
root.right.right = new Node(67);
root.left.left.left = new Node(57);
root.left.left.right = new Node(38);
root.left.right.left = new Node(9);
root.left.right.right = new Node(10);
root.right.left.left = new Node(110);
root.right.left.right = new Node(312);
root.right.right.left = new Node(131);
root.right.right.right = new Node(414);
root.right.left.right.left = new Node(8);
root.right.right.right.right = new Node(39);
count_with_greater_sum(root, 100);
Console.WriteLine(count);
}
}
// The code is contributed by Arushi Jindal.
Efficient Approach: The problem can be solved by maintaining 3 variables called grandparent, parent, and child. It can be done in constant space without using other data structures.
- Traverse the tree in preorder
- Maintain 3 variables called grandParent, parent, and child
- Whenever we have sum more than the target we can increase the count or print the triplet.
Below is the implementation of the above approach:
C++
// CPP implementation to print
// the nodes having a single child
#include <bits/stdc++.h>
using namespace std;
// Class of the Binary Tree node
struct Node
{
int data;
Node *left, *right;
Node(int x)
{
data = x;
left = right = NULL;
}
};
// global variable
int count = 0;
void preorder(Node* grandParent,
Node* parent,
Node* child,
int sum)
{
if(grandParent != NULL &&
parent != NULL &&
child != NULL &&
(grandParent -> data +
parent -> data +
child->data) > sum)
{
count++;
//uncomment below lines if you
// want to print triplets
/*System->out->print(grandParent
->data+"-->"+parent->data+"-->
"+child->data);
System->out->println();*/
}
if(child == NULL)
return;
preorder(parent, child,
child -> left, sum);
preorder(parent, child,
child -> right, sum);
}
//Driver code
int main()
{
Node *r10 = new Node(10);
Node *r1 = new Node(1);
Node *r22 = new Node(22);
Node *r35 = new Node(35);
Node *r4 = new Node(4);
Node *r15 = new Node(15);
Node *r67 = new Node(67);
Node *r57 = new Node(57);
Node *r38 = new Node(38);
Node *r9 = new Node(9);
Node *r10_2 = new Node(10);
Node *r110 = new Node(110);
Node *r312 = new Node(312);
Node *r131 = new Node(131);
Node *r414 = new Node(414);
Node *r8 = new Node(8);
Node *r39 = new Node(39);
r10 -> left = r1;
r10 -> right = r22;
r1 -> left = r35;
r1 -> right = r4;
r22 -> left = r15;
r22 -> right = r67;
r35 -> left = r57;
r35 -> right = r38;
r4 -> left = r9;
r4 -> right = r10_2;
r15 -> left = r110;
r15 -> right = r312;
r67 -> left = r131;
r67 -> right = r414;
r312 -> left = r8;
r414 -> right = r39;
preorder(NULL, NULL,
r10, 100);
cout << cont;
}
// This code is contributed by Mohit Kumar 29
Java
class Node{
int data;
Node left;
Node right;
public Node(int data)
{
this.data=data;
}
}
class TreeTriplet {
static int count=0; // global variable
public void preorder(Node grandParent,Node parent,Node child,int sum)
{
if(grandParent!=null && parent!=null && child!=null && (grandParent.data+parent.data+child.data) > sum)
{
count++;
//uncomment below lines if you want to print triplets
/*System.out.print(grandParent.data+"-->"+parent.data+"-->"+child.data);
System.out.println();*/
}
if(child==null)
return;
preorder(parent,child,child.left,sum);
preorder(parent,child,child.right,sum);
}
public static void main(String args[])
{
Node r10 = new Node(10);
Node r1 = new Node(1);
Node r22 = new Node(22);
Node r35 = new Node(35);
Node r4 = new Node(4);
Node r15 = new Node(15);
Node r67 = new Node(67);
Node r57 = new Node(57);
Node r38 = new Node(38);
Node r9 = new Node(9);
Node r10_2 = new Node(10);
Node r110 = new Node(110);
Node r312 = new Node(312);
Node r131 = new Node(131);
Node r414 = new Node(414);
Node r8 = new Node(8);
Node r39 = new Node(39);
r10.left=r1;
r10.right=r22;
r1.left=r35;
r1.right=r4;
r22.left=r15;
r22.right=r67;
r35.left=r57;
r35.right=r38;
r4.left=r9;
r4.right=r10_2;
r15.left=r110;
r15.right=r312;
r67.left=r131;
r67.right=r414;
r312.left=r8;
r414.right=r39;
TreeTriplet p = new TreeTriplet();
p.preorder(null, null, r10,100);
System.out.println(count);
}
}
// This code is contributed by Akshay Siddhpura
Python3
# Python3 program to implement
# the above approach
class Node:
def __init__(self,
data):
self.left = None
self.right = None
self.data = data
# global variable
count = 0
def preorder(grandParent, parent,
child, sum):
global count
if(grandParent != None and
parent != None and
child != None and
(grandParent.data +
parent.data +
child.data) > sum):
count += 1
# uncomment below lines if
# you want to print triplets
# System.out.print(grandParent.
# data+"-->"+parent.data+"-->
# "+child.data); System.out.println();
if(child == None):
return;
preorder(parent, child,
child.left, sum);
preorder(parent, child,
child.right, sum);
# Driver code
if __name__ == "__main__":
r10 = Node(10);
r1 = Node(1);
r22 = Node(22);
r35 = Node(35);
r4 = Node(4);
r15 = Node(15);
r67 = Node(67);
r57 = Node(57);
r38 = Node(38);
r9 = Node(9);
r10_2 = Node(10);
r110 = Node(110);
r312 = Node(312);
r131 = Node(131);
r414 = Node(414);
r8 = Node(8);
r39 = Node(39);
r10.left = r1;
r10.right = r22;
r1.left = r35;
r1.right = r4;
r22.left = r15;
r22.right = r67;
r35.left = r57;
r35.right = r38;
r4.left = r9;
r4.right = r10_2;
r15.left = r110;
r15.right = r312;
r67.left = r131;
r67.right = r414;
r312.left = r8;
r414.right = r39;
preorder(None, None,
r10, 100)
print(count);
# This code is contributed by Rutvik_56
C#
// C# program to find an index which has
// same number of even elements on left and
// right, Or same number of odd elements on
// left and right.
using System;
public class Node
{
public int data;
public Node left;
public Node right;
public Node(int data)
{
this.data = data;
}
}
class GFG
{
static int count = 0; // global variable
public void preorder(Node grandParent,
Node parent,
Node child, int sum)
{
if(grandParent != null && parent != null &&
child != null && (grandParent.data +
parent.data + child.data) > sum)
{
count++;
// uncomment below lines if you want to print triplets
/*System.out.print(grandParent.data+"-->"+parent.data+"-->"+child.data);
System.out.println();*/
}
if(child == null)
return;
preorder(parent,child,child.left,sum);
preorder(parent,child,child.right,sum);
}
// Driver Code
public static void Main(String []args)
{
Node r10 = new Node(10);
Node r1 = new Node(1);
Node r22 = new Node(22);
Node r35 = new Node(35);
Node r4 = new Node(4);
Node r15 = new Node(15);
Node r67 = new Node(67);
Node r57 = new Node(57);
Node r38 = new Node(38);
Node r9 = new Node(9);
Node r10_2 = new Node(10);
Node r110 = new Node(110);
Node r312 = new Node(312);
Node r131 = new Node(131);
Node r414 = new Node(414);
Node r8 = new Node(8);
Node r39 = new Node(39);
r10.left = r1;
r10.right = r22;
r1.left = r35;
r1.right = r4;
r22.left = r15;
r22.right = r67;
r35.left = r57;
r35.right = r38;
r4.left = r9;
r4.right = r10_2;
r15.left = r110;
r15.right = r312;
r67.left = r131;
r67.right = r414;
r312.left = r8;
r414.right = r39;
GFG p = new GFG();
p.preorder(null, null, r10,100);
Console.WriteLine(count);
}
}
// This code is contributed by 29AjayKumar
JavaScript
<script>
class Node
{
constructor(data)
{
this.data = data;
this.left = this.right = null;
}
}
let count = 0; // global variable
function preorder(grandParent, parent, child, sum)
{
if(grandParent != null && parent != null && child != null && (grandParent.data+parent.data+child.data) > sum)
{
count++;
// uncomment below lines if you want to print triplets
/* System.out.print(grandParent.data+"-->"+parent.data+"-->"+child.data);
System.out.println();*/
}
if(child == null)
return;
preorder(parent, child, child.left, sum);
preorder(parent, child, child.right, sum);
}
let r10 = new Node(10);
let r1 = new Node(1);
let r22 = new Node(22);
let r35 = new Node(35);
let r4 = new Node(4);
let r15 = new Node(15);
let r67 = new Node(67);
let r57 = new Node(57);
let r38 = new Node(38);
let r9 = new Node(9);
let r10_2 = new Node(10);
let r110 = new Node(110);
let r312 = new Node(312);
let r131 = new Node(131);
let r414 = new Node(414);
let r8 = new Node(8);
let r39 = new Node(39);
r10.left = r1;
r10.right = r22;
r1.left = r35;
r1.right = r4;
r22.left = r15;
r22.right = r67;
r35.left = r57;
r35.right = r38;
r4.left = r9;
r4.right = r10_2;
r15.left = r110;
r15.right = r312;
r67.left = r131;
r67.right = r414;
r312.left = r8;
r414.right = r39;
preorder(null, null, r10,100);
document.write(count);
// This code is contributed by unknown2108
</script>
Time complexity: O(n)
Auxiliary Space : The space complexity of the above code is O(1), as it does not use any additional data structures and only uses a few variables for storing intermediate values. (the recursion stack is not being considered for this approach).
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