Binary Trees
void preOrderList(Node *root, vector<int>& res)
if(root==NULL)
return;
res.push_back(root->data);
preOrderList(root->left,res);
preOrderList(root->right,res);
//Function to return a list containing the preorder traversal of the tree.
vector <int> preorder(Node* root)
vector<int> res;
preOrderList(root,res);
return res;
vector<int> inOrder(Node* root) {
vector<int> res;
inOrderTraversal(root,res);
return res;
void inOrderTraversal(Node *root, vector<int>& res)
if(root==NULL)
return;
inOrderTraversal(root->left,res);
res.push_back(root->data);
inOrderTraversal(root->right,res);
int height(struct Node* node){
// code here
if(node==NULL)
return 0;
return max(height(node->left),height(node->right))+1;
void kDistantFromLeafUtil(Node* node,int &counter,bool visited[],int pathLen,int k)
{
//base case
if (node==NULL) return;
visited[pathLen] = false;
pathLen++;
//if it's a leaf node, we increment the count but only if the
//same ancestor at distance k is not already counted.
if (node->left == NULL && node->right == NULL &&
pathLen-k-1 >= 0 && visited[pathLen-k-1] == false)
counter++;
//setting the ancestor as visited so that we won't count it again.
visited[pathLen-k-1] = true;
return;
//if the current node is not a leaf node then we call the function
//recursively for left and right subtrees.
kDistantFromLeafUtil(node->left, counter, visited, pathLen, k);
kDistantFromLeafUtil(node->right, counter, visited, pathLen, k);
//Function to return count of nodes at a given distance from leaf nodes.
int printKDistantfromLeaf(Node* node, int k)
int counter = 0;
bool visited[MAX_HEIGHT] = {false};
kDistantFromLeafUtil(node, counter, visited, 0, k);
//returning the count.
return counter;
vector<vector<int>> levelOrder(Node* node)
{
vector<vector<int>> ans;
queue<Node *> q;
q.push(node);
int size;
Node *aux = NULL;
while(!q.empty())
size = q.size();
vector<int> aux1;
for(int i = 0;i<size;i++)
aux = q.front();
q.pop();
aux1.push_back(aux->data);
if(aux->left!=NULL)
q.push(aux->left);
if(aux->right!=NULL)
q.push(aux->right);
ans.push_back(aux1);
return ans;
vector <int> zigZagTraversal(Node* root)
// Code here
vector<int> ans;
stack<int> s;
queue<Node *> q;
Node *aux = NULL;
q.push(root);
string direction = "right";
int size;
while(!q.empty())
size = q.size();
for(int i = 0;i<size;i++)
{
aux = q.front();
q.pop();
if(direction=="right")
ans.push_back(aux->data);
else
s.push(aux->data);
if(aux->left!=NULL)
q.push(aux->left);
if(aux->right!=NULL)
q.push(aux->right);
if(direction=="left")
while(!s.empty())
ans.push_back(s.top());
s.pop();
direction="right";
else
direction="left";
return ans;
vector<int> leftView(Node *root) {
// code here
vector<int> ans;
queue<Node *> q;
Node *aux = NULL;
int size;
q.push(root);
while(!q.empty())
{
size = q.size();
for(int i = 0;i<size;i++)
aux = q.front();
q.pop();
if(i==0)
ans.push_back(aux->data);
if(aux->left!=NULL)
q.push(aux->left);
if(aux->right!=NULL)
q.push(aux->right);
return ans;
int isSumProperty(Node *root)
if(ifSum(root))
return 1;
else
return 0;
bool ifSum(Node *root)
if(root==NULL)
return true;
if(root->left==NULL&&root->right==NULL)
return true;
int sum=0;
if(root->left!=NULL)
sum +=root->left->data;
if(root->right!=NULL)
sum+=root->right->data;
if(sum==root->data&&ifSum(root->left)&&ifSum(root->right))
return true;
}
void mirror(Node* node) {
// code here
if(node==NULL)
return;
Node *aux = node->left;
node->left = node->right;
node->right = aux;
mirror(node->left);
mirror(node->right);
bool isBalanced(Node *root)
if(root==NULL)
return true;
int lh = height(root->left);
int rh = height(root->right);
if(isBalanced(root->left)&&isBalanced(root->right)&&abs(lh-rh)<=1)
return true;
int height(Node *root)
if(root==NULL)
return 0;
return 1+max(height(root->left),height(root->right));
bool isSubTree(Node* T, Node* S)
if(T==NULL)
return false;
if(S==NULL)
return true;
if(checkIdentical(T,S))
return true;
return isSubTree(T->left,S)||isSubTree(T->right,S);
bool checkIdentical(Node *T,Node *S)
{
if(T==NULL&&S==NULL)
return true;
if(T==NULL||S==NULL)
return false;
return (T->data==S->data&&checkIdentical(T->right,S->right)&&checkIdentical(T->left,S->left));
bool isMirror(Node* r1, Node *r2)
if(r1==NULL&&r2==NULL)
return true;
if(r1==NULL||r2==NULL)
return false;
return isMirror(r1->left,r2->right)&&isMirror(r1->right,r2->left);
bool IsFoldable(Node* root)
if(root==NULL)
return true;
return isMirror(root->left,root->right);
int verticalWidth(Node* root) {
if (root == NULL) {
return 0;
map<int, int> verticalLines; // Tracks unique vertical lines
queue<pair<Node*, int>> q; // For level-order traversal
q.push({root, 0}); // Root is at horizontal distance 0
while (!q.empty()) {
auto front = q.front();
q.pop();
Node* node = front.first;
int distance = front.second;
verticalLines[distance]++; // Record the horizontal distance
if (node->left) {
q.push({node->left, distance - 1});
if (node->right) {
q.push({node->right, distance + 1});
return verticalLines.size();
void convertToDLL(Node* root, Node*& head, Node*& prev) {
if (!root) return;
convertToDLL(root->left, head, prev); // Convert left subtree
if (prev == NULL) {
head = root; // The first node becomes the head of the DLL
} else {
prev->right = root; // Link the previous node to the current node
root->left = prev; // Link the current node to the previous node
prev = root; // Update the previous node
convertToDLL(root->right, head, prev); // Convert right subtree
Node* binaryTreeToDLL(Node* root) {
Node* head = NULL;
Node* prev = NULL;
convertToDLL(root, head, prev);
return head;
Node *buildTree(vector<int> inorder, vector<int> postorder) {
// code here
unordered_map<int, int> m;
for (int i = 0; i < inorder.size(); i++) {
m[inorder[i]] = i; // Store index of each value in inorder
int postIndex = postorder.size() - 1; // Start from the last postorder element
// Call the recursive helper function
return constructTree(inorder, postorder, m, 0, inorder.size() - 1, postIndex);
Node* constructTree(vector<int>& inorder, vector<int>& postorder,
unordered_map<int, int>& m, int instart, int inend, int& postind) {
// Base case: if the start index exceeds the end index
if (instart > inend) {
return NULL; // No elements to construct the tree
// Get the current root from postorder and decrease postIndex
int curr = postorder[postind--];
Node* aux = new Node(curr); // Create a new node with the current root value
// Get the index of the current root in inorder
int index = m[curr];
// Build the right and left subtrees
aux->right = constructTree(inorder, postorder, m, index + 1, inend, postind);
aux->left = constructTree(inorder, postorder, m, instart, index - 1, postind);
return aux; // Return the constructed node
void convert(Node *head, TreeNode *&root) {
unordered_map<int, TreeNode *> m;
Node *aux = head;
int index = 0;
while(aux!=NULL)
m[index] = new TreeNode(aux->data);
index++;
aux = aux->next;
}
index = 0;
aux = head;
while(aux!=NULL)
if(m.find(2*index+1)!=m.end())
m[index]->left = m[2*index+1];
if(m.find(2*index+2)!=m.end())
m[index]->right = m[2*index+2];
aux = aux->next;
index++;
root = m[0];
int findMaxSum(Node* root)
int res = INT_MIN;
sumHelper(root,res);
return res;
int sumHelper(Node *root, int& res)
if(root==NULL)
return 0;
int lsum = sumHelper(root->left,res);
int rsum = sumHelper(root->right,res);
int single_sum = max(max(lsum,rsum)+root->data,root->data);
int max_top = max(single_sum,lsum+rsum+root->data);
res = max(res,max_top);
return single_sum;
}
Node* lca(Node* root ,int n1 ,int n2 )
if(root==NULL)
return NULL;
if(root->data==n1||root->data==n2)
return root;
Node *lh = lca(root->left,n1,n2);
Node *rh = lca(root->right,n1,n2);
if(lh!=NULL&&rh!=NULL)
return root;
else if(rh!=NULL&&lh==NULL)
return rh;
else if(rh==NULL&&lh!=NULL)
return lh;
else
return NULL;
int maxDiffHelper(Node *root, int &max_diff)
if(root==NULL)
return INT_MAX;
if(root->right==NULL&&root->left==NULL)
return root->data;
int lsmall = maxDiffHelper(root->left,max_diff);
int rsmall = maxDiffHelper(root->right,max_diff);
max_diff = max(max_diff,root->data-min(lsmall,rsmall));
return min(root->data,min(lsmall,rsmall));
int maxDiff(Node* root)
int max_diff = INT_MIN;
maxDiffHelper(root,max_diff);
return max_diff;
int countHelper(Node *root, int X, int& count)
if(root==NULL)
return 0;
int lsum = countHelper(root->left, X, count);
int rsum = countHelper(root->right,X,count);
if(root->data+lsum+rsum==X)
count++;
return root->data+lsum+rsum;
int countSubtreesWithSumX(Node* root, int X)
int count = 0;
countHelper(root,X,count);
return count;
int countHelper(Node* root, int X, int& count) {
if (root == NULL)
return 0;
int lsum = countHelper(root->left, X, count);
int rsum = countHelper(root->right, X, count);
if (root->data + lsum + rsum == X)
count++;
return root->data + lsum + rsum;
int countSubtreesWithSumX(Node* root, int X) {
int count = 0;
countHelper(root, X, count);
return count;
BST
bool checkBST(Node *root, int lbound, int rbound)
if(root==NULL)
return true;
return(root->key>lbound&&root->key<rbound&&checkBST(root->left,lbound,root->key)&&checkBST(root->right,root->key,rbound));
void fixBST(Node *root,vector<int> inorder)
vector<int> correct = sort(inorder.begin(),inorder.end());
int i = 0;
while(i<inorder.size())
if(inorder[i]!=correct[i])
break;
i++;
int first = inorder[i];
int second = correct[i];
cout << "The 2 nodes to be swapped is: " << first << " and " << second;
void inOrderTraversal(Node *root, vector<int>& inorder)
if(root==NULL)
return;
inOrderTraversal(root->left,inorder);
inorder.push_back(root->key);
inOrderTraversal(root->right,inorder)
bool givenSum(Node *root, int sum)
vector<int> inOrder;
inOrderTraversal(root,inOrder);
int i = 0;
int j = inOrder.size()-1;
while(j>=i)
if(inOrder[i]+inOrder[j]==sum)
return true;
else if(inOrder[i]+inOrder[j]<sum)
i++;
else
j--;
return false;
void verticalTree(Node *root, map<int,int> mp,int hd)
if(root==NULL)
return;
verticalTree(root->left,mp,hd-1);
mp[hd]=mp[hd]+root->key;
verticalTree(root->right,mp,hd+1);
void verticalSums(Node *root)
map<int,int> mp;
verticalTree(root,mp,0);
for(auto sum:mp)
cout << sum.second << " ";
void printVerticalNodes(Node *root)
queue<pair<Node *,int>> q;
map<int,vector<int>> mp;
q.push({root,0});
Node *aux = NULL;
while(!q.empty())
auto p = q.front();
q.pop();
Node *aux = p.first;
int hd = p.second;
mp[hd].push_back(aux->key);
if(aux->left!=NULL)
q.push({aux->left,hd-1});
if(aux->right!=NULL)
q.push({aux->right,hd+1});
for(auto values:mp)
vector<int> aux = mp.second;
for(auto val:aux)
cout << val << " ";
cout << endl;
void printTopView(Node *root)
queue<pair<Node *,int>> q;
map<int,vector<int>> mp;
q.push({root,0});
Node *aux = NULL;
while(!q.empty())
auto p = q.front();
q.pop();
Node *aux = p.first;
int hd = p.second;
mp[hd].push_back(aux->key);
if(aux->left!=NULL)
q.push({aux->left,hd-1});
}
if(aux->right!=NULL)
q.push({aux->right,hd+1});
for(auto values:mp)
cout << (mp.second)[0] << " ";
node* search(struct node* root, int key)
// Base Cases: root is null or key is present at root
if (root == NULL || root->key == key)
return root;
// Key is greater than root's key
if (root->key < key)
return search(root->right, key);
// Key is smaller than root's key
return search(root->left, key);
void insert(Node*& root, int key)
Node* node = new Node(key);
if (!root) {
root = node;
return;
Node* prev = NULL;
Node* temp = root;
while (temp) {
if (temp->val > key) {
prev = temp;
temp = temp->left;
}
else if (temp->val < key) {
prev = temp;
temp = temp->right;
if (prev->val > key)
prev->left = node;
else
prev->right = node;
struct node * minValueNode(struct node* node)
struct node* current = node;
/* loop down to find the leftmost leaf */
while (current->left != NULL)
current = current->left;
return current;
// Function to delete a given node from the BST
struct node* deleteNode(struct node* root, int key)
// base case
if (root == NULL) return root;
// If the key to be deleted is smaller than the root's key,
// then it lies in left subtree
if (key < root->key)
root->left = deleteNode(root->left, key);
// If the key to be deleted is greater than the root's key,
// then it lies in right subtree
else if (key > root->key)
root->right = deleteNode(root->right, key);
// if key is same as root's key, then This is the node
// to be deleted
else
// node with only one child or no child
if (root->left == NULL)
struct node *temp = root->right;
free(root);
return temp;
else if (root->right == NULL)
struct node *temp = root->left;
free(root);
return temp;
// node with two children: Get the inorder successor (smallest
// in the right subtree)
struct node* temp = minValueNode(root->right);
// Copy the inorder successor's content to this node
root->key = temp->key;
// Delete the inorder successor
root->right = deleteNode(root->right, temp->key);
return root;
int floor(Node* root, int key)
if (!root)
return INT_MAX;
/* If root->data is equal to key */
if (root->data == key)
return root->data;
/* If root->data is greater than the key */
if (root->data > key)
return floor(root->left, key);
/* Else, the floor may lie in right subtree
or may be equal to the root*/
int floorValue = floor(root->right, key);
return (floorValue <= key) ? floorValue : root->data;
Node* kthSmallest(Node* root, int& k)
// base case
if (root == NULL)
return NULL;
// search in left subtree
Node* left = kthSmallest(root->left, k);
// if k'th smallest is found in left subtree, return it
if (left != NULL)
return left;
// if current element is k'th smallest, return it
count++;
if (count == k)
return root;
// else search in right subtree
return kthSmallest(root->right, k);
Linked List
Node *insertAtBegin(Node *head, int x)
Node *temp = new Node(x);
temp->next = head;
head->prev = temp;
return temp;
Node *insertAtEnd(Node *head, int x)
Node *curr = head;
while((curr->next)!=NULL)
curr = curr->next;
Node *temp = new Node(x);
temp->prev = curr;
curr->next = temp;
return head;
Node *reverseList(Node *head)
Node *curr = head;
Node *temp;
curr->prev = curr->next;
curr->next = NULL;
curr = curr->prev;
while((curr->next)!=NULL)
temp = curr->next;
curr->next = curr->prev;
curr->prev = temp;
curr = curr->prev;
curr->next = curr->prev;
curr->prev = NULL;
return curr;
Node *deleteHead(Node *head)
Node *curr = head;
curr = curr->next;
curr->prev = NULL;
delete head;
return curr;
Node *deleteTail(Node *head)
Node *curr = head;
while((curr->next->next)!=NULL)
curr = curr->next;
delete curr->next;
curr->next = NULL;
return head;
void listTraversal(Node *head)
Node *curr = head;
while(curr!=NULL)
cout << curr->data << " ";
curr = curr->next;
Node *insertAtPosition(Node *head, int pos, int x)
Node *curr = head;
int curr_pos = 1;
while(curr_pos!=pos-1)
curr = curr->next;
curr_pos++;
Node *temp = new Node(x);
temp->next = curr->next;
curr->next = temp;
return head;
}
Node *deleteFirstNode(Node *head)
head = head->next;
return head;
Node *deleteTail(Node *head)
Node *curr = head;
while(curr->next->next!=NULL)
curr = curr->next;
curr->next = NULL;
return head;
int findPosition(Node *head, int x)
Node *curr = head;
int pos = 1;
while((curr!=NULL)&&(curr->data)!=x)
curr = curr->next;
pos++;
if(curr!=NULL)
return pos;
else
return -1;
Sorting
void bubbleSort(int arr[], int n) {
for(int i = 0;i<n-1;i++)
for(int j = 0;j<n-i-1;j++)
if(arr[j]>arr[j+1])
swap(arr[j],arr[j+1]);
vector<int> insertionSort(vector<int>& arr) {
int n = arr.size();
for (int i = 1; i < n; i++) {
int key = arr[i];
int j = i - 1;
// Move elements of arr[0..i-1], that are greater than key,
// to one position ahead of their current position
while (j >= 0 && arr[j] > key) {
arr[j + 1] = arr[j];
j--;
arr[j + 1] = key;
return arr;
vector<int> mergeThree(vector<int>& A, vector<int>& B, vector<int>& C)
//Your code here
int n1 = A.size();
int n2 = B.size();
int n3 = C.size();
vector<int> arr(n1+n2,0);
int i = 0;
int j = 0;
int index = 0;
while(i<n1 && j<n2)
{
if(A[i]<=B[j])
arr[index] = A[i];
i++;
else
arr[index] = B[j];
j++;
index++;
while(i<n1)
arr[index] = A[i];
i++;
index++;
while(j<n2)
arr[index] = B[j];
j++;
index++;
vector <int>ans(n1+n2+n3,0);
index = 0;
i = 0;
j = 0;
while(i<n1+n2 && j<n3)
if(arr[i]<=C[j])
ans[index] = arr[i];
i++;
else
{
ans[index] = C[j];
j++;
index++;
while(i<n1+n2)
ans[index] = arr[i];
i++;
index++;
while(j<n3)
ans[index] = C[j];
j++;
index++;
return ans;
void quickSort(int arr[], int low, int high)
if(high>low)
int p = partition(arr,low,high);
quickSort(arr,low,p-1);
quickSort(arr,p+1,high);
public:
int partition (int arr[], int low, int high)
// Your code here
int pivot = arr[high];
int i = low-1;
int j = low;
while(j<high)
{
if(arr[j]<pivot)
i++;
swap(arr[i],arr[j]);
j++;
i++;
swap(arr[i],arr[j]);
return i;
void threeWayPartition(vector<int>& array,int a, int b)
// code here
int l = 0;
int mid = 0;
int high = array.size()-1;
while(high>=mid)
if(array[mid]>=a && array[mid]<=b)
mid++;
else if(array[mid]<a)
swap(array[l],array[mid]);
l++;
mid++;
else
swap(array[high],array[mid]);
high--;
void merge(vector<int>& arr, int left, int mid, int right) {
int n1 = mid - left + 1;
int n2 = right - mid;
vector<int> leftArr(n1), rightArr(n2);
for (int i = 0; i < n1; i++)
leftArr[i] = arr[left + i];
for (int i = 0; i < n2; i++)
rightArr[i] = arr[mid + 1 + i];
int i = 0, j = 0, k = left;
while (i < n1 && j < n2) {
if (leftArr[i] <= rightArr[j]) {
arr[k++] = leftArr[i++];
} else {
arr[k++] = rightArr[j++];
while (i < n1) {
arr[k++] = leftArr[i++];
while (j < n2) {
arr[k++] = rightArr[j++];
void mergeSort(vector<int>& arr, int left, int right) {
if (left < right) {
int mid = left + (right - left) / 2;
mergeSort(arr, left, mid);
mergeSort(arr, mid + 1, right);
merge(arr, left, mid, right);