Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 64

1.

Calculate the Diameter of a Binary Tree


Problem Statement: Find the Diameter of a Binary Tree. Diameter is the length of
the longest path between any 2 nodes in the tree and this path may or may not pass
from the root.
class Solution {
public:
int diameterOfBinaryTree(TreeNode* root) {
int diameter = 0;
height(root, diameter);
return diameter;
}

private:
int height(TreeNode* node, int& diameter) {

if (!node) {
return 0;
}

int lh = height(node->left, diameter);


int rh = height(node->right, diameter);

diameter = max(diameter, lh + rh);

return 1 + max(lh, rh);


}
};
2.Maximum Sum Path in Binary Tree
Problem Statement: Write a program to find the maximum sum path in a binary tree. A
path in a binary tree is a sequence of nodes where every adjacent pair of nodes are
connected by an edge. A node can only appear in the sequence at most once. A path
need not pass from the root. We need to find the path with the maximum sum in the
binary tree.
#include <bits/stdc++.h>

using namespace std;

struct node {
int data;
struct node * left, * right;
};

int findMaxPathSum(node * root, int & maxi) {


if (root == NULL) return 0;

int leftMaxPath = max(0, findMaxPathSum(root -> left, maxi));


int rightMaxPath = max(0, findMaxPathSum(root -> right, maxi));
int val = root -> data;
maxi = max(maxi, (leftMaxPath + rightMaxPath) + val);
return max(leftMaxPath, rightMaxPath) + val;

int maxPathSum(node * root) {


int maxi = INT_MIN;
findMaxPathSum(root, maxi);
return maxi;

}
struct node * newNode(int data) {
struct node * node = (struct node * ) malloc(sizeof(struct node));
node -> data = data;
node -> left = NULL;
node -> right = NULL;

return (node);
}

int main() {

struct node * root = newNode(-10);


root -> left = newNode(9);
root -> right = newNode(20);
root -> right -> left = newNode(15);
root -> right -> right = newNode(7);

int answer = maxPathSum(root);


cout << "The Max Path Sum for this tree is " << answer;

return 0;
}
3.Bottom view of a Binary Tree
Problem Statement: Given a binary tree, print the bottom view from left to right. A
node is included in the bottom view if it can be seen when we look at the tree from
the bottom
class Solution {
public:
vector <int> bottomView(Node *root) {
vector<int> ans;
if(root == NULL) return ans;
map<int,int> mpp;
queue<pair<Node*, int>> q;
q.push({root, 0});
while(!q.empty()) {
auto it = q.front();
q.pop();
Node* node = it.first;
int line = it.second;
mpp[line] = node->data;

if(node->left != NULL) {
q.push({node->left, line-1});
}
if(node->right != NULL) {
q.push({node->right, line + 1});
}

for(auto it : mpp) {
ans.push_back(it.second);
}
return ans;
}
};
4.Lowest Common Ancestor for two given Nodes
Problem Statement: Given a binary tree, Find the Lowest Common Ancestor for two
given Nodes (x,y).

Lowest Common Ancestor(LCA): The lowest common ancestor is defined between two
nodes x and y as the lowest node in T that has both x and y as descendants (where
we allow a node to be a descendant of itself.
class Solution {
public:
TreeNode* lowestCommonAncestor(TreeNode* root, TreeNode* p, TreeNode* q) {
//base case
if (root == NULL || root == p || root == q) {
return root;
}
TreeNode* left = lowestCommonAncestor(root->left, p, q);
TreeNode* right = lowestCommonAncestor(root->right, p, q);

//result
if(left == NULL) {
return right;
}
else if(right == NULL) {
return left;
}
else { //both left and right are not null, we found our result
return root;
}
}
};
5.Construct A Binary Tree from Inorder and Preorder Traversal
In this article we will solve the most asked coding interview problem: Construct A
Binary Tree from Inorder and Preorder Traversal.

Construct A Binary Tree from Inorder and Preorder Traversal

Given the Inorder and Preorder Traversal of a binary tree, we need to construct the
unique binary tree represented by them.

#include <bits/stdc++.h>

using namespace std;

struct node {
int data;
struct node * left, * right;
};

struct node * newNode(int data) {


struct node * node = (struct node * ) malloc(sizeof(struct node));
node -> data = data;
node -> left = NULL;
node -> right = NULL;

return (node);
}
node * constructTree(vector < int > & preorder, int preStart, int preEnd, vector
< int > & inorder, int inStart, int inEnd, map < int, int > & mp) {
if (preStart > preEnd || inStart > inEnd) return NULL;

node * root = newNode(preorder[preStart]);


int elem = mp[root -> data];
int nElem = elem - inStart;

root -> left = constructTree(preorder, preStart + 1, preStart + nElem, inorder,


inStart, elem - 1, mp);
root -> right = constructTree(preorder, preStart + nElem + 1, preEnd, inorder,
elem + 1, inEnd, mp);

return root;
}

node * buildTree(vector < int > & preorder, vector < int > & inorder) {
int preStart = 0, preEnd = preorder.size() - 1;
int inStart = 0, inEnd = inorder.size() - 1;

map < int, int > mp;


for (int i = inStart; i <= inEnd; i++) {
mp[inorder[i]] = i;
}

return constructTree(preorder, preStart, preEnd, inorder, inStart, inEnd, mp);


}

int main() {

vector<int> preorder{10,20,40,50,30,60};
vector<int> inorder{40,20,50,10,60,30};
node * root = buildTree(preorder, inorder);
return 0;
}
6.Morris Preorder Traversal of a Binary Tree
Problem Statement: Morris Preorder Traversal of a Binary tree. Given a Binary Tree,
find the Morris preorder traversal of Binary Tree.

#include <bits/stdc++.h>

using namespace std;

struct node {
int data;
struct node * left, * right;
};

vector < int > preorderTraversal(node * root) {


vector < int > preorder;

node * cur = root;


while (cur != NULL) {
if (cur -> left == NULL) {
preorder.push_back(cur -> data);
cur = cur -> right;
} else {
node * prev = cur -> left;
while (prev -> right != NULL && prev -> right != cur) {
prev = prev -> right;
}

if (prev -> right == NULL) {


prev -> right = cur;
preorder.push_back(cur -> data);
cur = cur -> left;
} else {
prev -> right = NULL;
cur = cur -> right;
}
}
}
return preorder;
}

struct node * newNode(int data) {


struct node * node = (struct node * ) malloc(sizeof(struct node));
node -> data = data;
node -> left = NULL;
node -> right = NULL;

return (node);
}

int main() {

struct node * root = newNode(1);


root -> left = newNode(2);
root -> right = newNode(3);
root -> left -> left = newNode(4);
root -> left -> right = newNode(5);
root -> left -> right -> right = newNode(6);

vector < int > preorder;


preorder = preorderTraversal(root);

cout << "The Preorder Traversal is: ";


for (int i = 0; i < preorder.size(); i++) {
cout << preorder[i] << " ";
}

return 0;
}
7.Rotten Oranges : Min time to rot all oranges : BFS
Problem Statement: You will be given an m x n grid, where each cell has the
following values :

2 – represents a rotten orange


1 – represents a Fresh orange
0 – represents an Empty Cell
Every minute, if a Fresh Orange is adjacent to a Rotten Orange in 4-direction
( upward, downwards, right, and left ) it becomes Rotten.

Return the minimum number of minutes required such that none of the cells has a
Fresh Orange. If it’s not possible, return -1.

#include<bits/stdc++.h>
using namespace std;
int orangesRotting(vector<vector<int>>& grid) {
if(grid.empty()) return 0;
int m = grid.size(), n = grid[0].size(), days = 0, tot = 0, cnt = 0;
queue<pair<int, int>> rotten;
for(int i = 0; i < m; ++i){
for(int j = 0; j < n; ++j){
if(grid[i][j] != 0) tot++;
if(grid[i][j] == 2) rotten.push({i, j});
}
}

int dx[4] = {0, 0, 1, -1};


int dy[4] = {1, -1, 0, 0};

while(!rotten.empty()){
int k = rotten.size();
cnt += k;
while(k--){
int x = rotten.front().first, y = rotten.front().second;
rotten.pop();
for(int i = 0; i < 4; ++i){
int nx = x + dx[i], ny = y + dy[i];
if(nx < 0 || ny < 0 || nx >= m || ny >= n || grid[nx][ny] != 1)
continue;
grid[nx][ny] = 2;
rotten.push({nx, ny});
}
}
if(!rotten.empty()) days++;
}

return tot == cnt ? days : -1;


}

int main()
{
vector<vector<int>> v{ {2,1,1} , {1,1,0} , {0,1,1} } ;
int rotting = orangesRotting(v);
cout<<"Minimum Number of Minutes Required "<<rotting<<endl;

}
8.Word Ladder – I : G-29
Given are the two distinct words startWord and targetWord, and a list denoting
wordList of unique words of equal lengths. Find the length of the shortest
transformation sequence from startWord to targetWord.

In this problem statement, we need to keep the following conditions in mind:

A word can only consist of lowercase characters.


Only one letter can be changed in each transformation.
Each transformed word must exist in the wordList including the targetWord.
startWord may or may not be part of the wordList
#include <bits/stdc++.h>
using namespace std;

class Solution
{
public:
int wordLadderLength(string startWord, string targetWord,
vector<string> &wordList)
{
// Creating a queue ds of type {word,transitions to reach ‘word’}.
queue<pair<string, int>> q;

// BFS traversal with pushing values in queue


// when after a transformation, a word is found in wordList.
q.push({startWord, 1});

// Push all values of wordList into a set


// to make deletion from it easier and in less time complexity.
unordered_set<string> st(wordList.begin(), wordList.end());
st.erase(startWord);
while (!q.empty())
{
string word = q.front().first;
int steps = q.front().second;
q.pop();

// we return the steps as soon as


// the first occurence of targetWord is found.
if (word == targetWord)
return steps;

for (int i = 0; i < word.size(); i++)


{
// Now, replace each character of ‘word’ with char
// from a-z then check if ‘word’ exists in wordList.
char original = word[i];
for (char ch = 'a'; ch <= 'z'; ch++)
{
word[i] = ch;
// check if it exists in the set and push it in the queue.
if (st.find(word) != st.end())
{
st.erase(word);
q.push({word, steps + 1});
}
}
word[i] = original;
}
}
// If there is no transformation sequence possible
return 0;
}
};

int main()
{

vector<string> wordList = {"des", "der", "dfr", "dgt", "dfs"};


string startWord = "der", targetWord = "dfs";

Solution obj;

int ans = obj.wordLadderLength(startWord, targetWord, wordList);

cout << ans;


cout << endl;
return 0;
}
9.Number of Islands
Problem Statement: Given a grid of size NxM (N is the number of rows and M is the
number of columns in the grid) consisting of ‘0’s (Water) and ‘1’s(Land). Find the
number of islands.
Note: An island is surrounded by water and is formed by connecting adjacent lands
horizontally or vertically or diagonally i.e., in all 8 directions.
#include <bits/stdc++.h>
using namespace std;

class Solution {
private:
void bfs(int row, int col, vector<vector<int>> &vis, vector<vector<char>>&grid) {
// mark it visited
vis[row][col] = 1;
queue<pair<int,int>> q;
// push the node in queue
q.push({row, col});
int n = grid.size();
int m = grid[0].size();

// until the queue becomes empty


while(!q.empty()) {
int row = q.front().first;
int col = q.front().second;
q.pop();

// traverse in the neighbours and mark them if its a land


for(int delrow = -1; delrow<=1;delrow++) {
for(int delcol = -1; delcol <= 1; delcol++) {
int nrow = row + delrow;
int ncol = col + delcol;
// neighbour row and column is valid, and is an unvisited land
if(nrow >= 0 && nrow < n && ncol >= 0 && ncol < m
&& grid[nrow][ncol] == '1' && !vis[nrow][ncol]) {
vis[nrow][ncol] = 1;
q.push({nrow, ncol});
}
}
}
}
}
public:
// Function to find the number of islands.
int numIslands(vector<vector<char>>& grid) {
int n = grid.size();
int m = grid[0].size();
// create visited array and initialise to 0
vector<vector<int>> vis(n, vector<int>(m, 0));
int cnt = 0;
for(int row = 0; row < n ; row++) {
for(int col = 0; col < m ;col++) {
// if not visited and is a land
if(!vis[row][col] && grid[row][col] == '1') {
cnt++;
bfs(row, col, vis, grid);
}
}
}
return cnt;
}
};
int main() {
// n: row, m: column
vector<vector<char>> grid
{
{'0', '1', '1', '1', '0', '0', '0'},
{'0', '0', '1', '1', '0', '1', '0'}
};

Solution obj;
cout << obj.numIslands(grid) << endl;

return 0;
}
10.Course Schedule I and II | Pre-requisite Tasks | Topological Sort: G-24
Problem Statement I (Course Schedule): There are a total of n tasks you have to
pick, labeled from 0 to n-1. Some tasks may have prerequisites tasks, for example,
to pick task 0 you have to first finish tasks 1, which is expressed as a pair: [0,
1]

Given the total number of n tasks and a list of prerequisite pairs of size m. Find
the order of tasks you should pick to finish all tasks.

Note: There may be multiple correct orders, you need to return one of them. If it
is impossible to finish all tasks, return an empty array.
#include <bits/stdc++.h>
using namespace std;

class Solution
{
public:
vector<int> findOrder(int V, int m, vector<vector<int>> prerequisites)
{
vector<int> adj[V];
for (auto it : prerequisites) {
adj[it[1]].push_back(it[0]);
}

int indegree[V] = {0};


for (int i = 0; i < V; i++) {
for (auto it : adj[i]) {
indegree[it]++;
}
}

queue<int> q;
for (int i = 0; i < V; i++) {
if (indegree[i] == 0) {
q.push(i);
}
}
vector<int> topo;
while (!q.empty()) {
int node = q.front();
q.pop();
topo.push_back(node);
// node is in your topo sort
// so please remove it from the indegree

for (auto it : adj[node]) {


indegree[it]--;
if (indegree[it] == 0) q.push(it);
}
}

if (topo.size() == V) return topo;


return {};
}
};

int main() {

int N = 4;
int M = 3;

vector<vector<int>> prerequisites(3);
prerequisites[0].push_back(0);
prerequisites[0].push_back(1);

prerequisites[1].push_back(1);
prerequisites[1].push_back(2);

prerequisites[2].push_back(2);
prerequisites[2].push_back(3);

Solution obj;
vector<int> ans = obj.findOrder(N, M, prerequisites);

for (auto task : ans) {


cout << task << " ";
}
cout << endl;
return 0;
}
//
#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
bool isPossible(int V, vector<pair<int, int> >& prerequisites) {
vector<int> adj[V];
for (auto it : prerequisites) {
adj[it.first].push_back(it.second);
}

int indegree[V] = {0};


for (int i = 0; i < V; i++) {
for (auto it : adj[i]) {
indegree[it]++;
}
}
queue<int> q;
for (int i = 0; i < V; i++) {
if (indegree[i] == 0) {
q.push(i);
}
}
vector<int> topo;
while (!q.empty()) {
int node = q.front();
q.pop();
topo.push_back(node);
// node is in your topo sort
// so please remove it from the indegree

for (auto it : adj[node]) {


indegree[it]--;
if (indegree[it] == 0) q.push(it);
}
}

if (topo.size() == V) return true;


return false;

}
};

int main() {

vector<pair<int, int>> prerequisites;


int N = 4;
prerequisites.push_back({1, 0});
prerequisites.push_back({2, 1});
prerequisites.push_back({3, 2});

Solution obj;
bool ans = obj.isPossible(N, prerequisites);

if (ans) cout << "YES";


else cout << "NO";
cout << endl;

return 0;
}
11.Alien Dictionary – Topological Sort: G-26
Problem Statement: Given a sorted dictionary of an alien language having N words
and k starting alphabets of a standard dictionary. Find the order of characters in
the alien language.
#include <bits/stdc++.h>
using namespace std;

class Solution {
// works for multiple components
private:
vector<int> topoSort(int V, vector<int> adj[])
{
int indegree[V] = {0};
for (int i = 0; i < V; i++) {
for (auto it : adj[i]) {
indegree[it]++;
}
}

queue<int> q;
for (int i = 0; i < V; i++) {
if (indegree[i] == 0) {
q.push(i);
}
}
vector<int> topo;
while (!q.empty()) {
int node = q.front();
q.pop();
topo.push_back(node);
// node is in your topo sort
// so please remove it from the indegree

for (auto it : adj[node]) {


indegree[it]--;
if (indegree[it] == 0) q.push(it);
}
}

return topo;
}
public:
string findOrder(string dict[], int N, int K) {
vector<int>adj[K];
for (int i = 0; i < N - 1; i++) {
string s1 = dict[i];
string s2 = dict[i + 1];
int len = min(s1.size(), s2.size());
for (int ptr = 0; ptr < len; ptr++) {
if (s1[ptr] != s2[ptr]) {
adj[s1[ptr] - 'a'].push_back(s2[ptr] - 'a');
break;
}
}
}

vector<int> topo = topoSort(K, adj);


string ans = "";
for (auto it : topo) {
ans = ans + char(it + 'a');
}
return ans;
}
};

int main() {

int N = 5, K = 4;
string dict[] = {"baa", "abcd", "abca", "cab", "cad"};
Solution obj;
string ans = obj.findOrder(dict, N, K);
for (auto ch : ans)
cout << ch << ' ';
cout << endl;

return 0;
}
12.Dijkstra’s Algorithm – Using Set : G-33
Given a weighted, undirected, and connected graph of V vertices and an adjacency
list adj where adj[i] is a list of lists containing two integers where the first
integer of each list j denotes there is an edge between i and j, second integers
corresponds to the weight of that edge. You are given the source vertex S and You
have to Find the shortest distance of all the vertex from the source vertex S. You
have to return a list of integers denoting the shortest distance between each node
and Source vertex S.
#include<bits/stdc++.h>
using namespace std;

class Solution
{
public:
//Function to find the shortest distance of all the vertices
//from the source vertex S.
vector <int> dijkstra(int V, vector<vector<int>> adj[], int S)
{
// Create a set ds for storing the nodes as a pair {dist,node}
// where dist is the distance from source to the node.
// set stores the nodes in ascending order of the distances
set<pair<int,int>> st;

// Initialising dist list with a large number to


// indicate the nodes are unvisited initially.
// This list contains distance from source to the nodes.
vector<int> dist(V, 1e9);

st.insert({0, S});

// Source initialised with dist=0


dist[S] = 0;

// Now, erase the minimum distance node first from the set
// and traverse for all its adjacent nodes.
while(!st.empty()) {
auto it = *(st.begin());
int node = it.second;
int dis = it.first;
st.erase(it);

// Check for all adjacent nodes of the erased


// element whether the prev dist is larger than current or not.
for(auto it : adj[node]) {
int adjNode = it[0];
int edgW = it[1];

if(dis + edgW < dist[adjNode]) {


// erase if it was visited previously at
// a greater cost.
if(dist[adjNode] != 1e9)
st.erase({dist[adjNode], adjNode});
// If current distance is smaller,
// push it into the queue
dist[adjNode] = dis + edgW;
st.insert({dist[adjNode], adjNode});
}
}
}
// Return the list containing shortest distances
// from source to all the nodes.
return dist;
}
};

int main()
{
// Driver code.
int V = 3, E = 3, S = 2;
vector<vector<int>> adj[V];
vector<vector<int>> edges;
vector<int> v1{1, 1}, v2{2, 6}, v3{2, 3}, v4{0, 1}, v5{1, 3}, v6{0, 6};
int i = 0;
adj[0].push_back(v1);
adj[0].push_back(v2);
adj[1].push_back(v3);
adj[1].push_back(v4);
adj[2].push_back(v5);
adj[2].push_back(v6);

Solution obj;
vector<int> res = obj.dijkstra(V, adj, S);

for (int i = 0; i < V; i++)


{
cout << res[i] << " ";
}
cout << endl;
return 0;
}
13.G-38: Cheapest Flights Within K Stops
There are n cities and m edges connected by some number of flights. You are given
an array of flights where flights[i] = [ fromi, toi, pricei] indicates that there
is a flight from city fromi to city toi with cost price. You have also given three
integers src, dst, and k, and return the cheapest price from src to dst with at
most k stops. If there is no such route, return -1.
#include <bits/stdc++.h>
using namespace std;

class Solution
{
public:
int CheapestFLight(int n, vector<vector<int>> &flights,
int src, int dst, int K)
{
// Create the adjacency list to depict airports and flights in
// the form of a graph.
vector<pair<int, int>> adj[n];
for (auto it : flights)
{
adj[it[0]].push_back({it[1], it[2]});
}

// Create a queue which stores the node and their distances from the
// source in the form of {stops, {node, dist}} with ‘stops’ indicating
// the no. of nodes between src and current node.
queue<pair<int, pair<int, int>>> q;

q.push({0, {src, 0}});

// Distance array to store the updated distances from the source.


vector<int> dist(n, 1e9);
dist[src] = 0;

// Iterate through the graph using a queue like in Dijkstra with


// popping out the element with min stops first.
while (!q.empty())
{
auto it = q.front();
q.pop();
int stops = it.first;
int node = it.second.first;
int cost = it.second.second;

// We stop the process as soon as the limit for the stops reaches.
if (stops > K)
continue;
for (auto iter : adj[node])
{
int adjNode = iter.first;
int edW = iter.second;

// We only update the queue if the new calculated dist is


// less than the prev and the stops are also within limits.
if (cost + edW < dist[adjNode] && stops <= K)
{
dist[adjNode] = cost + edW;
q.push({stops + 1, {adjNode, cost + edW}});
}
}
}
// If the destination node is unreachable return ‘-1’
// else return the calculated dist from src to dst.
if (dist[dst] == 1e9)
return -1;
return dist[dst];
}
};

int main()
{
// Driver Code.
int n = 4, src = 0, dst = 3, K = 1;

vector<vector<int>> flights = {{0, 1, 100}, {1, 2, 100}, {2, 0, 100}, {1, 3,


600},
{2, 3, 200}};

Solution obj;
int ans = obj.CheapestFLight(n, flights, src, dst, K);

cout << ans;


cout << endl;

return 0;
}
14.Bellman Ford Algorithm: G-41
Problem Statement: Given a weighted, directed and connected graph of V vertices and
E edges, Find the shortest distance of all the vertices from the source vertex S.
#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
/* Function to implement Bellman Ford
* edges: vector of vectors which represents the graph
* S: source vertex to start traversing graph with
* V: number of vertices
*/
vector<int> bellman_ford(int V, vector<vector<int>>& edges, int S) {
vector<int> dist(V, 1e8);
dist[S] = 0;
for (int i = 0; i < V - 1; i++) {
for (auto it : edges) {
int u = it[0];
int v = it[1];
int wt = it[2];
if (dist[u] != 1e8 && dist[u] + wt < dist[v]) {
dist[v] = dist[u] + wt;
}
}
}
// Nth relaxation to check negative cycle
for (auto it : edges) {
int u = it[0];
int v = it[1];
int wt = it[2];
if (dist[u] != 1e8 && dist[u] + wt < dist[v]) {
return { -1};
}
}

return dist;
}
};

int main() {

int V = 6;
vector<vector<int>> edges(7, vector<int>(3));
edges[0] = {3, 2, 6};
edges[1] = {5, 3, 1};
edges[2] = {0, 1, 5};
edges[3] = {1, 5, -3};
edges[4] = {1, 2, -2};
edges[5] = {3, 4, -2};
edges[6] = {2, 4, 3};

int S = 0;
Solution obj;
vector<int> dist = obj.bellman_ford(V, edges, S);
for (auto d : dist) {
cout << d << " ";
}
cout << endl;

return 0;
}
15.Floyd Warshall Algorithm: G-42
Problem Statement: The problem is to find the shortest distances between every pair
of vertices in a given edge-weighted directed graph. The graph is represented as an
adjacency matrix of size n*n. Matrix[i][j] denotes the weight of the edge from i to
j. If Matrix[i][j]=-1, it means there is no edge from i to j.
#include <bits/stdc++.h>
using namespace std;

class Solution {
public:
void shortest_distance(vector<vector<int>>&matrix) {
int n = matrix.size();
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (matrix[i][j] == -1) {
matrix[i][j] = 1e9;
}
if (i == j) matrix[i][j] = 0;
}
}

for (int k = 0; k < n; k++) {


for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
matrix[i][j] = min(matrix[i][j],
matrix[i][k] + matrix[k][j]);
}
}
}

for (int i = 0; i < n; i++) {


for (int j = 0; j < n; j++) {
if (matrix[i][j] == 1e9) {
matrix[i][j] = -1;
}
}
}
}
};

int main() {
int V = 4;
vector<vector<int>> matrix(V, vector<int>(V, -1));
matrix[0][1] = 2;
matrix[1][0] = 1;
matrix[1][2] = 3;
matrix[3][0] = 3;
matrix[3][1] = 5;
matrix[3][2] = 4;

Solution obj;
obj.shortest_distance(matrix);

for (auto row : matrix) {


for (auto cell : row) {
cout << cell << " ";
}
cout << endl;
}

return 0;
}
16.Kruskal’s Algorithm – Minimum Spanning Tree : G-47
Problem Statement: Given a weighted, undirected, and connected graph of V vertices
and E edges. The task is to find the sum of weights of the edges of the Minimum
Spanning Tree.
#include <bits/stdc++.h>
using namespace std;

class DisjointSet {
vector<int> rank, parent, size;
public:
DisjointSet(int n) {
rank.resize(n + 1, 0);
parent.resize(n + 1);
size.resize(n + 1);
for (int i = 0; i <= n; i++) {
parent[i] = i;
size[i] = 1;
}
}

int findUPar(int node) {


if (node == parent[node])
return node;
return parent[node] = findUPar(parent[node]);
}

void unionByRank(int u, int v) {


int ulp_u = findUPar(u);
int ulp_v = findUPar(v);
if (ulp_u == ulp_v) return;
if (rank[ulp_u] < rank[ulp_v]) {
parent[ulp_u] = ulp_v;
}
else if (rank[ulp_v] < rank[ulp_u]) {
parent[ulp_v] = ulp_u;
}
else {
parent[ulp_v] = ulp_u;
rank[ulp_u]++;
}
}

void unionBySize(int u, int v) {


int ulp_u = findUPar(u);
int ulp_v = findUPar(v);
if (ulp_u == ulp_v) return;
if (size[ulp_u] < size[ulp_v]) {
parent[ulp_u] = ulp_v;
size[ulp_v] += size[ulp_u];
}
else {
parent[ulp_v] = ulp_u;
size[ulp_u] += size[ulp_v];
}
}
};
class Solution
{
public:
//Function to find sum of weights of edges of the Minimum Spanning Tree.
int spanningTree(int V, vector<vector<int>> adj[])
{
// 1 - 2 wt = 5
/// 1 - > (2, 5)
// 2 -> (1, 5)

// 5, 1, 2
// 5, 2, 1
vector<pair<int, pair<int, int>>> edges;
for (int i = 0; i < V; i++) {
for (auto it : adj[i]) {
int adjNode = it[0];
int wt = it[1];
int node = i;

edges.push_back({wt, {node, adjNode}});


}
}
DisjointSet ds(V);
sort(edges.begin(), edges.end());
int mstWt = 0;
for (auto it : edges) {
int wt = it.first;
int u = it.second.first;
int v = it.second.second;

if (ds.findUPar(u) != ds.findUPar(v)) {
mstWt += wt;
ds.unionBySize(u, v);
}
}

return mstWt;
}
};
int main() {

int V = 5;
vector<vector<int>> edges = {{0, 1, 2}, {0, 2, 1}, {1, 2, 1}, {2, 3, 2}, {3, 4,
1}, {4, 2, 2}};
vector<vector<int>> adj[V];
for (auto it : edges) {
vector<int> tmp(2);
tmp[0] = it[1];
tmp[1] = it[2];
adj[it[0]].push_back(tmp);

tmp[0] = it[0];
tmp[1] = it[2];
adj[it[1]].push_back(tmp);
}

Solution obj;
int mstWt = obj.spanningTree(V, adj);
cout << "The sum of all the edge weights: " << mstWt << endl;
return 0;
}
17.Accounts Merge – DSU: G-50
Problem Statement: Given a list of accounts where each element account [ i ] is a
list of strings, where the first element account [ i ][ 0 ] is a name, and the
rest of the elements are emails representing emails of the account.

Now, we would like to merge these accounts. Two accounts definitely belong to the
same person if there is some common email to both accounts. Note that even if two
accounts have the same name, they may belong to different people as people could
have the same name. A person can have any number of accounts initially, but all of
their accounts definitely have the same name.

After merging the accounts, return the accounts in the following format: the first
element of each account is the name, and the rest of the elements are emails in
sorted order.
#include <bits/stdc++.h>
using namespace std;
//User function Template for C++
class DisjointSet {
vector<int> rank, parent, size;
public:
DisjointSet(int n) {
rank.resize(n + 1, 0);
parent.resize(n + 1);
size.resize(n + 1);
for (int i = 0; i <= n; i++) {
parent[i] = i;
size[i] = 1;
}
}

int findUPar(int node) {


if (node == parent[node])
return node;
return parent[node] = findUPar(parent[node]);
}
void unionByRank(int u, int v) {
int ulp_u = findUPar(u);
int ulp_v = findUPar(v);
if (ulp_u == ulp_v) return;
if (rank[ulp_u] < rank[ulp_v]) {
parent[ulp_u] = ulp_v;
}
else if (rank[ulp_v] < rank[ulp_u]) {
parent[ulp_v] = ulp_u;
}
else {
parent[ulp_v] = ulp_u;
rank[ulp_u]++;
}
}

void unionBySize(int u, int v) {


int ulp_u = findUPar(u);
int ulp_v = findUPar(v);
if (ulp_u == ulp_v) return;
if (size[ulp_u] < size[ulp_v]) {
parent[ulp_u] = ulp_v;
size[ulp_v] += size[ulp_u];
}
else {
parent[ulp_v] = ulp_u;
size[ulp_u] += size[ulp_v];
}
}
};

class Solution {
public:
vector<vector<string>> accountsMerge(vector<vector<string>> &details) {
int n = details.size();
DisjointSet ds(n);
sort(details.begin(), details.end());
unordered_map<string, int> mapMailNode;
for (int i = 0; i < n; i++) {
for (int j = 1; j < details[i].size(); j++) {
string mail = details[i][j];
if (mapMailNode.find(mail) == mapMailNode.end()) {
mapMailNode[mail] = i;
}
else {
ds.unionBySize(i, mapMailNode[mail]);
}
}
}

vector<string> mergedMail[n];
for (auto it : mapMailNode) {
string mail = it.first;
int node = ds.findUPar(it.second);
mergedMail[node].push_back(mail);
}

vector<vector<string>> ans;
for (int i = 0; i < n; i++) {
if (mergedMail[i].size() == 0) continue;
sort(mergedMail[i].begin(), mergedMail[i].end());
vector<string> temp;
temp.push_back(details[i][0]);
for (auto it : mergedMail[i]) {
temp.push_back(it);
}
ans.push_back(temp);
}
sort(ans.begin(), ans.end());
return ans;
}
};

int main() {

vector<vector<string>> accounts = {{"John", "j1@com", "j2@com", "j3@com"},


{"John", "j4@com"},
{"Raj", "r1@com", "r2@com"},
{"John", "j1@com", "j5@com"},
{"Raj", "r2@com", "r3@com"},
{"Mary", "m1@com"}
};

Solution obj;
vector<vector<string>> ans = obj.accountsMerge(accounts);
for (auto acc : ans) {
cout << acc[0] << ":";
int size = acc.size();
for (int i = 1; i < size; i++) {
cout << acc[i] << " ";
}
cout << endl;
}
return 0;
}
19.Bridges in Graph – Using Tarjan’s Algorithm of time in and low time: G-55
Problem Statement: There are n servers numbered from 0 to n – 1 connected by
undirected server-to-server connections forming a network where connections[i] =
[ai, bi] represents a connection between servers ai and bi. Any server can reach
other servers directly or indirectly through the network.

A critical connection is a connection that, if removed, will make some servers


unable to reach some other servers.

Return all critical connections in the network in any order.

Note: Here servers mean the nodes of the graph. The prob
#include <bits/stdc++.h>
using namespace std;

class Solution {
private:
int timer = 1;
void dfs(int node, int parent, vector<int> &vis,
vector<int> adj[], int tin[], int low[], vector<vector<int>> &bridges)
{
vis[node] = 1;
tin[node] = low[node] = timer;
timer++;
for (auto it : adj[node]) {
if (it == parent) continue;
if (vis[it] == 0) {
dfs(it, node, vis, adj, tin, low, bridges);
low[node] = min(low[it], low[node]);
// node --- it
if (low[it] > tin[node]) {
bridges.push_back({it, node});
}
}
else {
low[node] = min(low[node], low[it]);
}
}
}
public:
vector<vector<int>> criticalConnections(int n,
vector<vector<int>>& connections) {
vector<int> adj[n];
for (auto it : connections) {
int u = it[0], v = it[1];
adj[u].push_back(v);
adj[v].push_back(u);
}
vector<int> vis(n, 0);
int tin[n];
int low[n];
vector<vector<int>> bridges;
dfs(0, -1, vis, adj, tin, low, bridges);
return bridges;
}
};

int main() {

int n = 4;
vector<vector<int>> connections = {
{0, 1}, {1, 2},
{2, 0}, {1, 3}
};

Solution obj;
vector<vector<int>> bridges = obj.criticalConnections(n, connections);
for (auto it : bridges) {
cout << "[" << it[0] << ", " << it[1] << "] ";
}
cout << endl;
return 0;
}
20.Kth largest/smallest element in an array
Problem Statement: Given an unsorted array, print Kth Largest and Smallest Element
from an unsorted array.
#include <bits/stdc++.h>
using namespace std ;
class Solution {

public:

void kth_Largest_And_Smallest_By_AscendingOrder(vector<int>&arr, int k) {

sort(arr.begin(), arr.end()) ;
int n = arr.size() ;

cout << "kth Largest element " << arr[n - k] << ", " <<
"kth Smallest element " << arr[k - 1];
}
} ;
int main() {

vector<int>arr = {1, 2, 6, 4, 5, 3} ;

Solution obj ;

obj.kth_Largest_And_Smallest_By_AscendingOrder(arr, 3) ;

return 0 ;
}
Output: kth Largest element 4, kth
#include <bits/stdc++.h>
using namespace std ;

class Solution {

public:

void kth_Largest_MaxHeap(vector<int>&arr, int k) {

priority_queue<int>pq ;
int n = arr.size() ;

for (int i = 0; i < arr.size(); i++) {


pq.push(arr[i]) ;
}

int f = k - 1 ;

while (f > 0) {
pq.pop() ;
f-- ;
}

cout << "Kth Largest element " << pq.top() << "\n" ;
}

void kth_Smallest_MinHeap(vector<int>&arr, int k) {

priority_queue<int, vector<int>, greater<int>>pq ;


int n = arr.size() ;

for (int i = 0; i < arr.size(); i++) {


pq.push(arr[i]) ;
}
int f = k - 1 ;

while (f > 0) {
pq.pop() ;
f-- ;
}

cout << "Kth Smallest element " << pq.top() << "\n" ;
}
} ;
int main() {

vector<int>arr = {1, 2, 6, 4, 5, 3} ;

Solution obj ;
obj.kth_Largest_MaxHeap(arr, 3) ;
obj.kth_Smallest_MinHeap(arr, 3) ;

return 0 ;
}
Output:
Code for kth largest element:

#include <bits/stdc++.h>
using namespace std ;

int partition(vector<int>& arr, int left, int right) {


int pivot = arr[left] ;
int l = left + 1 ;
int r = right;
while (l <= r) {
if (arr[l] < pivot && arr[r] > pivot) {
swap(arr[l], arr[r]);
l++ ;
r-- ;
}
if (arr[l] >= pivot) {
l++;
}
if (arr[r] <= pivot) {
r--;
}
}
swap(arr[left], arr[r]);
return r;
}

int kth_Largest_Element(vector<int>& arr, int k) {


int left = 0, right = arr.size() - 1, kth;
while (1) {
int idx = partition(arr, left, right);
if (idx == k - 1) {
kth = arr[idx];
break;
}
if (idx < k - 1) {
left = idx + 1;
} else {
right = idx - 1;
}
}
return kth;
}

int main() {

vector<int>arr ;
arr.push_back(12) ;
arr.push_back(3) ;
arr.push_back(5) ;
arr.push_back(7) ;
arr.push_back(4) ;
arr.push_back(19) ;
arr.push_back(26) ;

int n = arr.size(), k = 1;
cout << "Kth Largest element is " << kth_Largest_Element(arr, k);
return 0 ;
}
Output: Kth Largest element is 26

Time complexity: O(n) , where n = size of the array

Space complexity: O(1)

code for Kth Smallest element:

#include<bits/stdc++.h>
using namespace std;

int partition(vector<int>&arr, int l, int r)


{
int f = arr[r] ;
int i = l;

for (int j = l; j <= r - 1; j++) {


if (arr[j] <= f) {
swap(arr[i], arr[j]) ;
i++;
}
}
swap(arr[i], arr[r]);
return i;
}

int kth_Smallest_Element(vector<int>&arr, int l, int r, int k)


{
if (k <= r - l + 1 && k > 0) {

int ind = partition(arr, l, r);

if (ind - l == k - 1) {
return arr[ind];
}
if (ind - l > k - 1) {
return kth_Smallest_Element(arr, l, ind - 1, k);
}

return kth_Smallest_Element(arr, ind + 1, r, k - ind + l - 1);


}
return INT_MAX;
}

int main()
{

vector<int>arr ;
arr.push_back(12) ;
arr.push_back(3) ;
arr.push_back(5) ;
arr.push_back(7) ;
arr.push_back(4) ;
arr.push_back(19) ;
arr.push_back(26) ;

int n = arr.size(), k = 1;
cout << "Kth smallest element is " << kth_Smallest_Element(arr, 0, n - 1, k);
return 0;
}
21.Next Greater Element Using Stack
Problem Statement: Given a circular integer array A, return the next greater
element for every element in A. The next greater element for an element x is the
first element greater than x that we come across while traversing the array in a
clockwise manner. If it doesn’t exist, return -1 for this element.
#include<bits/stdc++.h>

using namespace std;


class Solution {
public:
vector < int > nextGreaterElements(vector < int > & nums) {
int n = nums.size();
vector < int > nge(n, -1);
stack < int > st;
for (int i = 2 * n - 1; i >= 0; i--) {
while (!st.empty() && st.top() <= nums[i % n]) {
st.pop();
}

if (i < n) {
if (!st.empty()) nge[i] = st.top();
}
st.push(nums[i % n]);
}
return nge;
}
};
int main() {
Solution obj;
vector < int > v {5,7,1,2,6,0};
vector < int > res = obj.nextGreaterElements(v);
cout << "The next greater elements are" << endl;
for (int i = 0; i < res.size(); i++) {
cout << res[i] << " ";
}
}
22.Trapping Rainwater
Problem Statement: Given an array of non-negative integers representation elevation
of ground. Your task is to find the water that can be trapped after rain.
#include<bits/stdc++.h>

using namespace std;


int trap(vector < int > & arr) {
int n = arr.size();
int waterTrapped = 0;
for (int i = 0; i < n; i++) {
int j = i;
int leftMax = 0, rightMax = 0;
while (j >= 0) {
leftMax = max(leftMax, arr[j]);
j--;
}
j = i;
while (j < n) {
rightMax = max(rightMax, arr[j]);
j++;
}
waterTrapped += min(leftMax, rightMax) - arr[i];
}
return waterTrapped;
}

int main() {
vector < int > arr;
arr = {0,1,0,2,1,0,1,3,2,1,2,1};
cout << "The water that can be trapped is " << trap(arr) << endl;
}
Output: The water that can be trapped is 6

Time Complexity: O(N*N) as for each index we are calculating leftMax and rightMax
so it is a nested loop.

Space Complexity: O(1).

Solution 2:Better solution

Intuition: We are taking O(N) for computing leftMax and rightMax at each index. The
complexity can be boiled down to O(1) if we precompute the leftMax and rightMax at
each index.

Approach: Take 2 array prefix and suffix array and precompute the leftMax and
rightMax for each index beforehand. Then use the formula min(prefix[I], suffix[i])-
arr[i] to compute water trapped at each index.

Code:

#include<bits/stdc++.h>

using namespace std;


int trap(vector < int > & arr) {
int n = arr.size();
int prefix[n], suffix[n];
prefix[0] = arr[0];
for (int i = 1; i < n; i++) {
prefix[i] = max(prefix[i - 1], arr[i]);
}
suffix[n - 1] = arr[n - 1];
for (int i = n - 2; i >= 0; i--) {
suffix[i] = max(suffix[i + 1], arr[i]);
}
int waterTrapped = 0;
for (int i = 0; i < n; i++) {
waterTrapped += min(prefix[i], suffix[i]) - arr[i];
}
return waterTrapped;
}

int main() {
vector < int > arr;
arr = {0,1,0,2,1,0,1,3,2,1,2,1};
cout << "The water that can be trapped is " << trap(arr) << endl;
}
Output: The water that can be trapped is 6

Time Complexity: O(3*N) as we are traversing through the array only once. And
O(2*N) for computing prefix and suffix array.

Space Complexity: O(N)+O(N) for prefix and suffix arrays.

Solution 3:Optimal Solution(Two pointer approach)

Approach: Take 2 pointers l(left pointer) and r(right pointer) pointing to 0th and
(n-1)th index respectively. Take two variables leftMax and rightMax and initialize
them to 0. If height[l] is less than or equal to height[r] then if leftMax is less
than height[l] update leftMax to height[l] else add leftMax-height[l] to your final
answer and move the l pointer to the right i.e l++. If height[r] is less than
height[l], then now we are dealing with the right block. If height[r] is greater
than rightMax, then update rightMax to height[r] else add rightMax-height[r] to the
final answer. Now move r to the left. Repeat these steps till l and r crosses each
other.

Intuition: We need a minimum of leftMax and rightMax.So if we take the case when
height[l]<=height[r] we increase l++, so we can surely say that there is a block
with a height more than height[l] to the right of l. And for the same reason when
height[r]<=height[l] we can surely say that there is a block to the left of r which
is at least of height[r]. So by traversing these cases and using two pointers
approach the time complexity can be decreased without using extra space.

Code:

#include<bits/stdc++.h>

using namespace std;


int trap(vector < int > & height) {
int n = height.size();
int left = 0, right = n - 1;
int res = 0;
int maxLeft = 0, maxRight = 0;
while (left <= right) {
if (height[left] <= height[right]) {
if (height[left] >= maxLeft) {
maxLeft = height[left];
} else {
res += maxLeft - height[left];
}
left++;
} else {
if (height[right] >= maxRight) {
maxRight = height[right];
} else {
res += maxRight - height[right];
}
right--;
}
}
return res;
}

int main() {
vector < int > arr;
arr = {0,1,0,2,1,0,1,3,2,1,2,1};
cout << "The water that can be trapped is " << trap(arr) << endl;
}
Output: The water that can be trapped is 6

Time Complexity: O(N) because we are using 2 pointer approach.

Space Complexity: O(1) because we are not using anything extra.

Special thanks to Pranav Padawe and Sudip Ghosh for contributing to this article on
takeUforward. If you also wish to share your knowledge with the takeUforward fam,
please check out this article

24.Area of largest rectangle in Histogram


Problem Statement: Given an array of integers heights representing the histogram’s
bar height where the width of each bar is 1 return the area of the largest
rectangle in histogram.

Example:
#include <bits/stdc++.h>

using namespace std;


// Brute Force Approach to find largest rectangle area in Histogram
int largestarea(int arr[], int n) {
int maxArea = 0;
for (int i = 0; i < n; i++) {
int minHeight = INT_MAX;
for (int j = i; j < n; j++) {
minHeight = min(minHeight, arr[j]);
maxArea = max(maxArea, minHeight * (j - i + 1));
}
}
return maxArea;
}
int main() {
int arr[] = {2, 1, 5, 6, 2, 3, 1};
int n = 7;
cout << "The largest area in the histogram is " << largestarea(arr, n); //
Printing the largest rectangle area
return 0;
}
#include <bits/stdc++.h>

using namespace std;


class Solution {
public:
int largestRectangleArea(vector < int > & heights) {
int n = heights.size();
stack < int > st;
int leftsmall[n], rightsmall[n];
for (int i = 0; i < n; i++) {
while (!st.empty() && heights[st.top()] >= heights[i]) {
st.pop();
}
if (st.empty())
leftsmall[i] = 0;
else
leftsmall[i] = st.top() + 1;
st.push(i);
}
// clear the stack to be re-used
while (!st.empty())
st.pop();

for (int i = n - 1; i >= 0; i--) {


while (!st.empty() && heights[st.top()] >= heights[i])
st.pop();

if (st.empty())
rightsmall[i] = n - 1;
else
rightsmall[i] = st.top() - 1;

st.push(i);
}
int maxA = 0;
for (int i = 0; i < n; i++) {
maxA = max(maxA, heights[i] * (rightsmall[i] - leftsmall[i] + 1));
}
return maxA;
}
};
int main() {
vector<int> heights = {2, 1, 5, 6, 2, 3, 1};
Solution obj;
cout << "The largest area in the histogram is " <<
obj.largestRectangleArea(heights);
return 0;
}
#include <bits/stdc++.h>

using namespace std;


class Solution {
public:
int largestRectangleArea(vector < int > & histo) {
stack < int > st;
int maxA = 0;
int n = histo.size();
for (int i = 0; i <= n; i++) {
while (!st.empty() && (i == n || histo[st.top()] >= histo[i])) {
int height = histo[st.top()];
st.pop();
int width;
if (st.empty())
width = i;
else
width = i - st.top() - 1;
maxA = max(maxA, width * height);
}
st.push(i);
}
return maxA;
}
};
int main() {
vector < int > histo = {2, 1, 5, 6, 2, 3, 1};
Solution obj;
cout << "The largest area in the histogram is " <<
obj.largestRectangleArea(histo) << endl;
return 0;
}
Output:
26.Sliding Window Maximum
Problem Statement: Given an array of integers arr, there is a sliding window of
size k which is moving from the very left of the array to the very right. You can
only see the k numbers in the window. Each time the sliding window moves right by
one position. Return the max sliding window.
#include<bits/stdc++.h>

using namespace std;

void GetMax(vector < int > nums, int l, int r, vector < int > & arr) {
int i, maxi = INT_MIN;
for (i = l; i <= r; i++)
maxi = max(maxi, nums[i]);
arr.push_back(maxi);
}
vector < int > maxSlidingWindow(vector < int > & nums, int k) {
int left = 0, right = 0;
int i, j;
vector < int > arr;
while (right < k - 1) {
right++;
}
while (right < nums.size()) {
GetMax(nums, left, right, arr);
left++;
right++;
}
return arr;
}
int main() {
int i, j, n, k = 3, x;
vector < int > arr {
4,0,
-1,
3,
5,
3,
6,
8};
vector < int > ans;
ans = maxSlidingWindow(arr, k);
cout << "Maximum element in every " << k << " window " << endl;
for (i = 0; i < ans.size(); i++)
cout << ans[i] << " ";
return 0;
}
///
#include<bits/stdc++.h>

using namespace std;

vector < int > maxSlidingWindow(vector < int > & nums, int k) {
deque < int > dq;
vector < int > ans;
for (int i = 0; i < nums.size(); i++) {
if (!dq.empty() && dq.front() == i - k) dq.pop_front();

while (!dq.empty() && nums[dq.back()] < nums[i])


dq.pop_back();

dq.push_back(i);
if (i >= k - 1) ans.push_back(nums[dq.front()]);
}
return ans;
}
int main() {
int i, j, n, k = 3, x;
vector < int > arr {4,0,-1,3,5,3,6,8};
vector < int > ans;
ans = maxSlidingWindow(arr, k);
cout << "Maximum element in every " << k << " window " << endl;
for (i = 0; i < ans.size(); i++)
cout << ans[i] << " ";
return 0;
}
Output:
27.Implement LRU Cache
Problem Statement: “Design a data structure that follows the constraints of Least
Recently Used (LRU) cache”.

Implement the LRUCache class:

LRUCache(int capacity) we need to initialize the LRU cache with positive size
capacity.
int get(int key) returns the value of the key if the key exists, otherwise return -
1.
Void put(int key,int value), Update the value of the key if the key exists.
Otherwise, add the key-value pair to the cache.if the number of keys exceeds the
capacity from this operation, evict the least recently used key.
class LRUCache {
public:
class node {
public:
int key;
int val;
node * next;
node * prev;
node(int _key, int _val) {
key = _key;
val = _val;
}
};

node * head = new node(-1, -1);


node * tail = new node(-1, -1);

int cap;
unordered_map < int, node * > m;

LRUCache(int capacity) {
cap = capacity;
head -> next = tail;
tail -> prev = head;
}

void addnode(node * newnode) {


node * temp = head -> next;
newnode -> next = temp;
newnode -> prev = head;
head -> next = newnode;
temp -> prev = newnode;
}

void deletenode(node * delnode) {


node * delprev = delnode -> prev;
node * delnext = delnode -> next;
delprev -> next = delnext;
delnext -> prev = delprev;
}

int get(int key_) {


if (m.find(key_) != m.end()) {
node * resnode = m[key_];
int res = resnode -> val;
m.erase(key_);
deletenode(resnode);
addnode(resnode);
m[key_] = head -> next;
return res;
}

return -1;
}

void put(int key_, int value) {


if (m.find(key_) != m.end()) {
node * existingnode = m[key_];
m.erase(key_);
deletenode(existingnode);
}
if (m.size() == cap) {
m.erase(tail -> prev -> key);
deletenode(tail -> prev);
}
addnode(new node(key_, value));
m[key_] = head -> next;
}
};
29.Power Set: Print all the possible subsequences of the String
Problem Statement: Given a string, find all the possible subsequences of the
string.
#include<bits/stdc++.h>
using namespace std;
vector<string> AllPossibleStrings(string s) {
int n = s.length();
vector<string>ans;
for (int num = 0; num < (1 << n); num++) {
string sub = "";
for (int i = 0; i < n; i++) {
//check if the ith bit is set or not
if (num & (1 << i)) {
sub += s[i];
}
}
if (sub.length() > 0) {
ans.push_back(sub);
}
}
sort(ans.begin(), ans.end());
return ans;
}
int main()
{

string s="abc";
vector<string>ans = AllPossibleStrings(s);
//printint all the subsequence.
cout<<"All possible subsequences are "<<endl;
for (auto it : ans) {
cout << it << " ";
}

}
#include<bits/stdc++.h>
using namespace std;
void solve(int i, string s, string &f) {
if (i == s.length()) {
cout << f << " ";
return;
}
//picking
f = f + s[i];
solve(i + 1, s, f);
//poping out while backtracking
f.pop_back();
solve(i + 1, s, f);
}
int main() {
string s = "abc";
string f = "";
cout<<"All possible subsequences are: "<<endl;
solve(0, s, f);
}
30.Combination Sum – 1
Problem Statement:

Given an array of distinct integers and a target, you have to return the list of
all unique combinations where the chosen numbers sum to target. You may return the
combinations in any order.

The same number may be chosen from the given array an unlimited number of times.
Two combinations are unique if the frequency of at least one of the chosen numbers
is different.

It is guaranteed that the number of unique combinations that sum up to target is


less than 150 combinations for the given input.
#include<bits/stdc++.h>

using namespace std;


class Solution {
public:
void findCombination(int ind, int target, vector < int > & arr, vector < vector
< int >> & ans, vector < int > & ds) {
if (ind == arr.size()) {
if (target == 0) {
ans.push_back(ds);
}
return;
}
// pick up the element
if (arr[ind] <= target) {
ds.push_back(arr[ind]);
findCombination(ind, target - arr[ind], arr, ans, ds);
ds.pop_back();
}

findCombination(ind + 1, target, arr, ans, ds);

}
public:
vector < vector < int >> combinationSum(vector < int > & candidates, int
target) {
vector < vector < int >> ans;
vector < int > ds;
findCombination(0, target, candidates, ans, ds);
return ans;
}
};
int main() {
Solution obj;
vector < int > v {2,3,6,7};
int target = 7;

vector < vector < int >> ans = obj.combinationSum(v, target);


cout << "Combinations are: " << endl;
for (int i = 0; i < ans.size(); i++) {
for (int j = 0; j < ans[i].size(); j++)
cout << ans[i][j] << " ";
cout << endl;
}
}
31.N Queen Problem | Return all Distinct Solutions to the N-Queens Puzzle
Problem Statement: The n-queens is the problem of placing n queens on n × n
chessboard such that no two queens can attack each other. Given an integer n,
return all distinct solutions to the n -queens puzzle. Each solution contains a
distinct boards configuration of the queen’s placement, where ‘Q’ and ‘.’ indicate
queen and empty space respectively.
#include <bits/stdc++.h>

using namespace std;


class Solution {
public:
bool isSafe1(int row, int col, vector < string > board, int n) {
// check upper element
int duprow = row;
int dupcol = col;

while (row >= 0 && col >= 0) {


if (board[row][col] == 'Q')
return false;
row--;
col--;
}

col = dupcol;
row = duprow;
while (col >= 0) {
if (board[row][col] == 'Q')
return false;
col--;
}

row = duprow;
col = dupcol;
while (row < n && col >= 0) {
if (board[row][col] == 'Q')
return false;
row++;
col--;
}
return true;
}

public:
void solve(int col, vector < string > & board, vector < vector < string >> &
ans, int n) {
if (col == n) {
ans.push_back(board);
return;
}
for (int row = 0; row < n; row++) {
if (isSafe1(row, col, board, n)) {
board[row][col] = 'Q';
solve(col + 1, board, ans, n);
board[row][col] = '.';
}
}
}
public:
vector < vector < string >> solveNQueens(int n) {
vector < vector < string >> ans;
vector < string > board(n);
string s(n, '.');
for (int i = 0; i < n; i++) {
board[i] = s;
}
solve(0, board, ans, n);
return ans;
}
};
int main() {
int n = 4; // we are taking 4*4 grid and 4 queens
Solution obj;
vector < vector < string >> ans = obj.solveNQueens(n);
for (int i = 0; i < ans.size(); i++) {
cout << "Arrangement " << i + 1 << "\n";
for (int j = 0; j < ans[0].size(); j++) {
cout << ans[i][j];
cout << endl;
}
cout << endl;
}
return 0;
}
//
#include <bits/stdc++.h>

using namespace std;


class Solution {
public:
void solve(int col, vector < string > & board, vector < vector < string >> &
ans, vector < int > & leftrow, vector < int > & upperDiagonal, vector < int > &
lowerDiagonal, int n) {
if (col == n) {
ans.push_back(board);
return;
}
for (int row = 0; row < n; row++) {
if (leftrow[row] == 0 && lowerDiagonal[row + col] == 0 && upperDiagonal[n -
1 + col - row] == 0) {
board[row][col] = 'Q';
leftrow[row] = 1;
lowerDiagonal[row + col] = 1;
upperDiagonal[n - 1 + col - row] = 1;
solve(col + 1, board, ans, leftrow, upperDiagonal, lowerDiagonal, n);
board[row][col] = '.';
leftrow[row] = 0;
lowerDiagonal[row + col] = 0;
upperDiagonal[n - 1 + col - row] = 0;
}
}
}

public:
vector < vector < string >> solveNQueens(int n) {
vector < vector < string >> ans;
vector < string > board(n);
string s(n, '.');
for (int i = 0; i < n; i++) {
board[i] = s;
}
vector < int > leftrow(n, 0), upperDiagonal(2 * n - 1, 0), lowerDiagonal(2 *
n - 1, 0);
solve(0, board, ans, leftrow, upperDiagonal, lowerDiagonal, n);
return ans;
}
};
int main() {
int n = 4; // we are taking 4*4 grid and 4 queens
Solution obj;
vector < vector < string >> ans = obj.solveNQueens(n);
for (int i = 0; i < ans.size(); i++) {
cout << "Arrangement " << i + 1 << "\n";
for (int j = 0; j < ans[0].size(); j++) {
cout << ans[i][j];
cout << endl;
}
cout << endl;
}
return 0;
}
Output:

Arrangement 1
..Q.
Q…
…Q
.Q..

Arrangement 2
.Q..
33.Sudoku Solver
Problem Statement:

Given a 9×9 incomplete sudoku, solve it such that it becomes valid sudoku. Valid
sudoku has the following properties.

1. All the rows should be filled with numbers(1 – 9) exactly once.

2. All the columns should be filled with numbers(1 – 9) exactly once.

3. Each 3×3 submatrix should be filled with numbers(1 – 9) exactly once.


#include <iostream>

#include <vector>

using namespace std;

bool isValid(vector < vector < char >> & board, int row, int col, char c) {
for (int i = 0; i < 9; i++) {
if (board[i][col] == c)
return false;

if (board[row][i] == c)
return false;
if (board[3 * (row / 3) + i / 3][3 * (col / 3) + i % 3] == c)
return false;
}
return true;
}

bool solveSudoku(vector < vector < char >> & board) {


for (int i = 0; i < board.size(); i++) {
for (int j = 0; j < board[0].size(); j++) {
if (board[i][j] == '.') {
for (char c = '1'; c <= '9'; c++) {
if (isValid(board, i, j, c)) {
board[i][j] = c;

if (solveSudoku(board))
return true;
else
board[i][j] = '.';
}
}

return false;
}
}
}
return true;
}
int main() {
vector<vector<char>>board{
{'9', '5', '7', '.', '1', '3', '.', '8', '4'},
{'4', '8', '3', '.', '5', '7', '1', '.', '6'},
{'.', '1', '2', '.', '4', '9', '5', '3', '7'},
{'1', '7', '.', '3', '.', '4', '9', '.', '2'},
{'5', '.', '4', '9', '7', '.', '3', '6', '.'},
{'3', '.', '9', '5', '.', '8', '7', '.', '1'},
{'8', '4', '5', '7', '9', '.', '6', '1', '3'},
{'.', '9', '1', '.', '3', '6', '.', '7', '5'},
{'7', '.', '6', '1', '8', '5', '4', '.', '9'}
};

solveSudoku(board);

for(int i= 0; i< 9; i++){


for(int j= 0; j< 9; j++)
cout<<board[i][j]<<" ";
cout<<"\n";
}
return 0;
}
35.M – Coloring Problem
Problem Statement: Given an undirected graph and a number m, determine if the graph
can be colored with at most m colors such that no two adjacent vertices of the
graph are colored with the same color.
#include<bits/stdc++.h>

using namespace std;


bool isSafe(int node, int color[], bool graph[101][101], int n, int col) {
for (int k = 0; k < n; k++) {
if (k != node && graph[k][node] == 1 && color[k] == col) {
return false;
}
}
return true;
}
bool solve(int node, int color[], int m, int N, bool graph[101][101]) {
if (node == N) {
return true;
}

for (int i = 1; i <= m; i++) {


if (isSafe(node, color, graph, N, i)) {
color[node] = i;
if (solve(node + 1, color, m, N, graph)) return true;
color[node] = 0;
}

}
return false;
}

//Function to determine if graph can be coloured with at most M colours such


//that no two adjacent vertices of graph are coloured with same colour.
bool graphColoring(bool graph[101][101], int m, int N) {
int color[N] = {
0
};
if (solve(0, color, m, N, graph)) return true;
return false;
}

int main() {
int N = 4;
int m = 3;

bool graph[101][101];
memset(graph, false, sizeof graph);

// Edges are (0, 1), (1, 2), (2, 3), (3, 0), (0, 2)
graph[0][1] = 1; graph[1][0] = 1;
graph[1][2] = 1; graph[2][1] = 1;
graph[2][3] = 1; graph[3][2] = 1;
graph[3][0] = 1; graph[0][3] = 1;
graph[0][2] = 1; graph[2][0] = 1;

cout << graphColoring(graph, m, N);

}
36.Word Search – Leetcode
Given an m x n grid of characters board and a string word, return true if the word
exists in the grid. The word can be constructed from letters of sequentially
adjacent cells, where adjacent cells are horizontally or vertically neighboring.
The same letter cell may not be used more than once.

#include<bits/stdc++.h>
using namespace std;

bool searchNext(vector<vector<char>> &board, string word, int row, int col,


int index, int m, int n) {
// if index reaches at the end that means we have found the word
if (index == word.length())
return true;

// Checking the boundaries if the character at which we are placed is not


//the required character
if (row < 0 || col < 0 || row == m || col == n || board[row][col] !=
word[index] or board[row][col] == '!')
return false;

// this is to prevent reusing of the same character


char c = board[row][col];
board[row][col] = '!';

// top direction
bool top = searchNext(board, word, row - 1, col, index + 1, m, n);
// right direction
bool right = searchNext(board, word, row, col + 1, index + 1, m, n);
// bottom direction
bool bottom = searchNext(board, word, row + 1, col, index + 1, m, n);
// left direction
bool left = searchNext(board, word, row, col - 1, index + 1, m, n);

board[row][col] = c; // undo change

return top || right || bottom || left;


}
bool exist(vector<vector<char>> board, string word) {

int m = board.size();
int n = board[0].size();

int index = 0;

// First search the first character


for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {

if (board[i][j] == word[index]) {
if (searchNext(board, word, i, j, index, m, n))
return true;
}
}
}

return false;
}

int main() {
vector<vector<char>> board {{'A','B','C','E'},
{'S','F','C','S'},
{'A','D','E','E'}};

string word = "ABCCED";

bool res = exist(board, word);


if(res==1)
cout<<"True"<<endl;
else
cout<<"False"<<endl;
}
40.Find middle element in a Linked List
Problem Statement: Given the head of a singly linked list, return the middle node
of the linked list. If there are two middle nodes, return the second middle node.
class Solution {
public:
ListNode* middleNode(ListNode* head) {
int n = 0;
ListNode* temp = head;
while(temp) {
n++;
temp = temp->next;
}

temp = head;

for(int i = 0; i < n / 2; i++) {


temp = temp->next;
}

return temp;
}
};
Solution 2: [Efficient] Tortoise-Hare-Approach

Unlike the above approach, we don’t have to maintain node count here and we will be
able to find the middle node in a single traversal so this approach is more
efficient.

Intuition: In the Tortoise-Hare approach, we increment slow ptr by 1 and fast ptr
by 2, so if take a close look fast ptr will travel double that of the slow pointer.
So when the fast ptr will be at the end of the Linked List, slow ptr would have
covered half of the Linked List till then. So slow ptr will be pointing towards the
middle of Linked List.

Approach:

Create two pointers slow and fast and initialize them to a head pointer.
Move slow ptr by one step and simultaneously fast ptr by two steps until fast ptr
is NULL or next of fast ptr is NULL.
When the above condition is met, we can see that the slow ptr is pointing towards
the middle of the Linked List and hence we can return the slow pointer.
Code:

/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/

class Solution {
public:
ListNode* middleNode(ListNode* head) {
ListNode *slow = head, *fast = head;
while (fast && fast->next)
slow = slow->next, fast = fast->next->next;
return slow;
}
};
Time Complexity: O(N)

Space Complexity: O(1)

Follow-up question you can try: Detect and remove Loop in Linked List

Special thanks to Aditya Shahare and Sudip Ghosh for contributing to this article
on takeUforward. If you also wish to share your knowledge with the takeUforward
fam, please check out this article.

41.Detect a Cycle in a Linked List


In this article, we will solve the most asked interview question: Detect a Cycle in
a Linked List

Problem Statement: Given head, the head of a linked list, determine if the linked
list has a cycle in it. There is a cycle in a linked list if there is some node in
the list that can be reached again by continuously following the next pointer.

Return true if there is a cycle in the linked list. Otherwise, return false.
#include<bits/stdc++.h>
using namespace std;

class node {
public:
int num;
node* next;
node(int val) {
num = val;
next = NULL;
}
};

//utility function to insert node in the list


void insertNode(node* &head,int val) {
node* newNode = new node(val);

if(head == NULL) {
head = newNode;
return;
}

node* temp = head;


while(temp->next != NULL) temp = temp->next;

temp->next = newNode;
return;
}

//utility function to create cycle


void createCycle(node* &head,int a,int b) {
int cnta = 0,cntb = 0;
node* p1 = head;
node* p2 = head;
while(cnta != a || cntb != b) {
if(cnta != a) p1 = p1->next, ++cnta;
if(cntb != b) p2 = p2->next, ++cntb;
}
p2->next = p1;
}

//utility function to detect cycle


bool cycleDetect(node* head) {
unordered_set<node*> hashTable;
while(head != NULL) {
if(hashTable.find(head) != hashTable.end()) return true;
hashTable.insert(head);
head = head->next;
}
return false;
}

int main() {
node* head = NULL;
insertNode(head,1);
insertNode(head,2);
insertNode(head,3);
insertNode(head,4);
createCycle(head,1,3);//creating cycle in the list
if(cycleDetect(head) == true)
cout<<"Cycle detected\n";
else
cout<<"Cycle not detected\n";
return 0;
}//
#include<bits/stdc++.h>
using namespace std;

class node {
public:
int num;
node* next;
node(int val) {
num = val;
next = NULL;
}
};

//utility function to insert node in the list


void insertNode(node* &head,int val) {
node* newNode = new node(val);

if(head == NULL) {
head = newNode;
return;
}

node* temp = head;


while(temp->next != NULL) temp = temp->next;

temp->next = newNode;
return;
}

//utility function to create cycle


void createCycle(node* &head,int a,int b) {
int cnta = 0,cntb = 0;
node* p1 = head;
node* p2 = head;
while(cnta != a || cntb != b) {
if(cnta != a) p1 = p1->next, ++cnta;
if(cntb != b) p2 = p2->next, ++cntb;
}
p2->next = p1;
}

//utility function to detect cycle


bool cycleDetect(node* head) {
if(head == NULL) return false;
node* fast = head;
node* slow = head;

while(fast->next != NULL && fast->next->next != NULL) {


fast = fast->next->next;
slow = slow->next;
if(fast == slow) return true;
}
return false;
}

int main() {
node* head = NULL;
insertNode(head,1);
insertNode(head,2);
insertNode(head,3);
insertNode(head,4);
createCycle(head,1,3);//creating cycle in the list
if(cycleDetect(head) == true)
cout<<"Cycle detected\n";
else
cout<<"Cycle not detected\n";
return 0;
}
Output: Cycle detected
43.Remove N-th node from the end of a Linked List
Problem Statement: Given a linked list, and a number N. Find the Nth node from the
end of this linked list and delete it. Return the head of the new modified linked
list.
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode * start = new ListNode();
start -> next = head;
ListNode* fast = start;
ListNode* slow = start;

for(int i = 1; i <= n; ++i)


fast = fast->next;
while(fast->next != NULL)
{
fast = fast->next;
slow = slow->next;
}

slow->next = slow->next->next;

return start->next;
}
};
45.Find intersection of Two Linked Lists
Problem Statement: Given the heads of two singly linked-lists headA and headB,
return the node at which the two lists intersect. If the two linked lists have no
intersection at all, return null.
#include<iostream>
using namespace std;

class node {
public:
int num;
node* next;
node(int val) {
num = val;
next = NULL;
}
};
//utility function to insert node at the end of the linked list
void insertNode(node* &head,int val) {
node* newNode = new node(val);

if(head == NULL) {
head = newNode;
return;
}

node* temp = head;


while(temp->next != NULL) temp = temp->next;

temp->next = newNode;
return;
}

//utility function to check presence of intersection


node* intersectionPresent(node* head1,node* head2) {
while(head2 != NULL) {
node* temp = head1;
while(temp != NULL) {
//if both nodes are same
if(temp == head2) return head2;
temp = temp->next;
}
head2 = head2->next;
}
//intersection is not present between the lists return null
return NULL;
}

//utility function to print linked list created


void printList(node* head) {
while(head->next != NULL) {
cout<<head->num<<"->";
head = head->next;
}
cout<<head->num<<endl;
}

int main() {
// creation of both lists
node* head = NULL;
insertNode(head,1);
insertNode(head,3);
insertNode(head,1);
insertNode(head,2);
insertNode(head,4);
node* head1 = head;
head = head->next->next->next;
node* headSec = NULL;
insertNode(headSec,3);
node* head2 = headSec;
headSec->next = head;
//printing of the lists
cout<<"List1: "; printList(head1);
cout<<"List2: "; printList(head2);
//checking if intersection is present
node* answerNode = intersectionPresent(head1,head2);
if(answerNode == NULL )
cout<<"No intersection\n";
else
cout<<"The intersection point is "<<answerNode->num<<endl;
return 0;
}
Output:

List1: 1->3->1->2->4
//
#include<bits/stdc++.h>
using namespace std;

class node {
public:
int num;
node* next;
node(int val) {
num = val;
next = NULL;
}
};
//utility function to insert node at the end of the linked list
void insertNode(node* &head,int val) {
node* newNode = new node(val);

if(head == NULL) {
head = newNode;
return;
}

node* temp = head;


while(temp->next != NULL) temp = temp->next;

temp->next = newNode;
return;
}

//utility function to check presence of intersection


node* intersectionPresent(node* head1,node* head2) {
unordered_set<node*> st;
while(head1 != NULL) {
st.insert(head1);
head1 = head1->next;
}
while(head2 != NULL) {
if(st.find(head2) != st.end()) return head2;
head2 = head2->next;
}
return NULL;

//utility function to print linked list created


void printList(node* head) {
while(head->next != NULL) {
cout<<head->num<<"->";
head = head->next;
}
cout<<head->num<<endl;
}

int main() {
// creation of both lists
node* head = NULL;
insertNode(head,1);
insertNode(head,3);
insertNode(head,1);
insertNode(head,2);
insertNode(head,4);
node* head1 = head;
head = head->next->next->next;
node* headSec = NULL;
insertNode(headSec,3);
node* head2 = headSec;
headSec->next = head;
//printing of the lists
cout<<"List1: "; printList(head1);
cout<<"List2: "; printList(head2);
//checking if intersection is present
node* answerNode = intersectionPresent(head1,head2);
if(answerNode == NULL )
cout<<"No intersection\n";
else
cout<<"The intersection point is "<<answerNode->num<<endl;
return 0;
}
//
#include<bits/stdc++.h>
using namespace std;
class node {
public:
int num;
node* next;
node(int val) {
num = val;
next = NULL;
}
};
//utility function to insert node at the end of the linked list
void insertNode(node* &head,int val) {
node* newNode = new node(val);

if(head == NULL) {
head = newNode;
return;
}

node* temp = head;


while(temp->next != NULL) temp = temp->next;

temp->next = newNode;
return;
}
int getDifference(node* head1,node* head2) {
int len1 = 0,len2 = 0;
while(head1 != NULL || head2 != NULL) {
if(head1 != NULL) {
++len1; head1 = head1->next;
}
if(head2 != NULL) {
++len2; head2 = head2->next;
}

}
return len1-len2;//if difference is neg-> length of list2 > length of list1
else vice-versa
}

//utility function to check presence of intersection


node* intersectionPresent(node* head1,node* head2) {
int diff = getDifference(head1,head2);
if(diff < 0)
while(diff++ != 0) head2 = head2->next;
else while(diff-- != 0) head1 = head1->next;
while(head1 != NULL) {
if(head1 == head2) return head1;
head2 = head2->next;
head1 = head1->next;
}
return head1;

//utility function to print linked list created


void printList(node* head) {
while(head->next != NULL) {
cout<<head->num<<"->";
head = head->next;
}
cout<<head->num<<endl;
}

int main() {
// creation of both lists
node* head = NULL;
insertNode(head,1);
insertNode(head,3);
insertNode(head,1);
insertNode(head,2);
insertNode(head,4);
node* head1 = head;
head = head->next->next->next;
node* headSec = NULL;
insertNode(headSec,3);
node* head2 = headSec;
headSec->next = head;
//printing of the lists
cout<<"List1: "; printList(head1);
cout<<"List2: "; printList(head2);
//checking if intersection is present
node* answerNode = intersectionPresent(head1,head2);
if(answerNode == NULL )
cout<<"No intersection\n";
else
cout<<"The intersection point is "<<answerNode->num<<endl;
return 0;
}
Output:
//
#include<bits/stdc++.h>
using namespace std;

class node {
public:
int num;
node* next;
node(int val) {
num = val;
next = NULL;
}
};
//utility function to insert node at the end of the linked list
void insertNode(node* &head,int val) {
node* newNode = new node(val);

if(head == NULL) {
head = newNode;
return;
}

node* temp = head;


while(temp->next != NULL) temp = temp->next;

temp->next = newNode;
return;
}
//utility function to check presence of intersection
node* intersectionPresent(node* head1,node* head2) {
node* d1 = head1;
node* d2 = head2;

while(d1 != d2) {
d1 = d1 == NULL? head2:d1->next;
d2 = d2 == NULL? head1:d2->next;
}

return d1;
}

//utility function to print linked list created


void printList(node* head) {
while(head->next != NULL) {
cout<<head->num<<"->";
head = head->next;
}
cout<<head->num<<endl;
}

int main() {
// creation of both lists
node* head = NULL;
insertNode(head,1);
insertNode(head,3);
insertNode(head,1);
insertNode(head,2);
insertNode(head,4);
node* head1 = head;
head = head->next->next->next;
node* headSec = NULL;
insertNode(headSec,3);
node* head2 = headSec;
headSec->next = head;
//printing of the lists
cout<<"List1: "; printList(head1);
cout<<"List2: "; printList(head2);
//checking if intersection is present
node* answerNode = intersectionPresent(head1,head2);
if(answerNode == NULL )
cout<<"No intersection\n";
else
cout<<"The intersection point is "<<answerNode->num<<endl;
return 0;
}
//45.Search Element in Rotated Sorted Array II
Problem Statement: Given an integer array arr of size N, sorted in ascending order
(may contain duplicate values) and a target value k. Now the array is rotated at
some pivot point unknown to you. Return True if k is present and otherwise, return
False.

#include <bits/stdc++.h>
using namespace std;

bool searchInARotatedSortedArrayII(vector<int>&arr, int k) {


int n = arr.size(); // size of the array.
for (int i = 0; i < n; i++) {
if (arr[i] == k) return true;
}
return false;
}

int main()
{
vector<int> arr = {7, 8, 1, 2, 3, 3, 3, 4, 5, 6};
int k = 3;
bool ans = searchInARotatedSortedArrayII(arr, k);
if (!ans)
cout << "Target is not present.\n";
else
cout << "Target is present in the array.\n";
return 0;
}
50.Minimum in Rotated Sorted Array
Problem Statement: Given an integer array arr of size N, sorted in ascending order
(with distinct values). Now the array is rotated between 1 to N times which is
unknown. Find the minimum element in the array.

#include <bits/stdc++.h>
using namespace std;

int findMin(vector<int>& arr) {


int n = arr.size(); // size of the array.
int mini = INT_MAX;
for (int i = 0; i < n; i++) {
// Always keep the minimum.
mini = min(mini, arr[i]);
}
return mini;
}

int main()
{
vector<int> arr = {4, 5, 6, 7, 0, 1, 2, 3};
int ans = findMin(arr);
cout << "The minimum element is: " << ans << "\n";
return 0;
}
50.
Peak element in Array
Problem Statement: Given an array of length N. Peak element is defined as the
element greater than both of its neighbors. Formally, if ‘arr[i]’ is the peak
element, ‘arr[i – 1]’ < ‘arr[i]’ and ‘arr[i + 1]’ < ‘arr[i]’. Find the index(0-
based) of a peak element in the array. If there are multiple peak numbers, return
the index of any peak number.
#include <bits/stdc++.h>
using namespace std;

int findPeakElement(vector<int> &arr) {


int n = arr.size(); //Size of array.

for (int i = 0; i < n; i++) {


//Checking for the peak:
if ((i == 0 || arr[i - 1] < arr[i])
&& (i == n - 1 || arr[i] > arr[i + 1])) {
return i;
}
}
// Dummy return statement
return -1;
}

int main()
{
vector<int> arr = {1, 2, 3, 4, 5, 6, 7, 8, 5, 1};
int ans = findPeakElement(arr);
cout << "The peak is at index: " << ans << "\n";
return 0;
}
66.Koko Eating Bananas
Problem Statement: A monkey is given ‘n’ piles of bananas, whereas the ‘ith’ pile
has ‘a[i]’ bananas. An integer ‘h’ is also given, which denotes the time (in hours)
for all the bananas to be eaten.

Each hour, the monkey chooses a non-empty pile of bananas and eats ‘k’ bananas. If
the pile contains less than ‘k’ bananas, then the monkey consumes all the bananas
and won’t eat any more bananas in that hour.

Find the minimum number of bananas ‘k’ to eat per hour so that the monkey can eat
all the bananas within ‘h’ hours.

#include <bits/stdc++.h>
using namespace std;

int findMax(vector<int> &v) {


int maxi = INT_MIN;
int n = v.size();
//find the maximum:
for (int i = 0; i < n; i++) {
maxi = max(maxi, v[i]);
}
return maxi;
}

int calculateTotalHours(vector<int> &v, int hourly) {


int totalH = 0;
int n = v.size();
//find total hours:
for (int i = 0; i < n; i++) {
totalH += ceil((double)(v[i]) / (double)(hourly));
}
return totalH;
}

int minimumRateToEatBananas(vector<int> v, int h) {


//Find the maximum number:
int maxi = findMax(v);

//Find the minimum value of k:


for (int i = 1; i <= maxi; i++) {
int reqTime = calculateTotalHours(v, i);
if (reqTime <= h) {
return i;
}
}

//dummy return statement


return maxi;
}

int main()
{
vector<int> v = {7, 15, 6, 3};
int h = 8;
int ans = minimumRateToEatBananas(v, h);
cout << "Koko should eat atleast " << ans << " bananas/hr.\n";
return 0;
}
67.Aggressive Cows : Detailed Solution
Problem Statement: You are given an array ‘arr’ of size ‘n’ which denotes the
position of stalls.
You are also given an integer ‘k’ which denotes the number of aggressive cows.
You are given the task of assigning stalls to ‘k’ cows such that the minimum
distance between any two of them is the maximum possible.
Find the maximum possible minimum distance.

#include <bits/stdc++.h>
using namespace std;

bool canWePlace(vector<int> &stalls, int dist, int cows) {


int n = stalls.size(); //size of array
int cntCows = 1; //no. of cows placed
int last = stalls[0]; //position of last placed cow.
for (int i = 1; i < n; i++) {
if (stalls[i] - last >= dist) {
cntCows++; //place next cow.
last = stalls[i]; //update the last location.
}
if (cntCows >= cows) return true;
}
return false;
}
int aggressiveCows(vector<int> &stalls, int k) {
int n = stalls.size(); //size of array
//sort the stalls[]:
sort(stalls.begin(), stalls.end());
int limit = stalls[n - 1] - stalls[0];
for (int i = 1; i <= limit; i++) {
if (canWePlace(stalls, i, k) == false) {
return (i - 1);
}
}
return limit;
}

int main()
{
vector<int> stalls = {0, 3, 4, 7, 10, 9};
int k = 4;
int ans = aggressiveCows(stalls, k);
cout << "The maximum possible minimum distance is: " << ans << "\n";
return 0;
}
65.Allocate Minimum Number of Pages
Problem Statement: Given an array ‘arr of integer numbers, ‘ar[i]’ represents the
number of pages in the ‘i-th’ book. There are a ‘m’ number of students, and the
task is to allocate all the books to the students.
Allocate books in such a way that:

Each student gets at least one book.


Each book should be allocated to only one student.
Book allocation should be in a contiguous manner.
You have to allocate the book to ‘m’ students such that the maximum number of pages
assigned to a student is minimum. If the allocation of books is not possible.
return -1

#include <bits/stdc++.h>
using namespace std;

int countStudents(vector<int> &arr, int pages) {


int n = arr.size(); //size of array.
int students = 1;
long long pagesStudent = 0;
for (int i = 0; i < n; i++) {
if (pagesStudent + arr[i] <= pages) {
//add pages to current student
pagesStudent += arr[i];
}
else {
//add pages to next student
students++;
pagesStudent = arr[i];
}
}
return students;
}

int findPages(vector<int>& arr, int n, int m) {


//book allocation impossible:
if (m > n) return -1;

int low = *max_element(arr.begin(), arr.end());


int high = accumulate(arr.begin(), arr.end(), 0);

for (int pages = low; pages <= high; pages++) {


if (countStudents(arr, pages) == m) {
return pages;
}
}
return low;
}

int main()
{
vector<int> arr = {25, 46, 28, 49, 24};
int n = 5;
int m = 4;
int ans = findPages(arr, n, m);
cout << "The answer is: " << ans << "\n";
return 0;
}
61.Median of Two Sorted Arrays of different sizes
Problem Statement: Given two sorted arrays arr1 and arr2 of size m and n
respectively, return the median of the two sorted arrays. The median is defined as
the middle value of a sorted list of numbers. In case the length of the list is
even, the median is the average of the two middle elements.

#include <bits/stdc++.h>
using namespace std;

double median(vector<int>& a, vector<int>& b) {


//size of two given arrays:
int n1 = a.size(), n2 = b.size();

vector<int> arr3;
//apply the merge step:
int i = 0, j = 0;
while (i < n1 && j < n2) {
if (a[i] < b[j]) arr3.push_back(a[i++]);
else arr3.push_back(b[j++]);
}

//copy the left-out elements:


while (i < n1) arr3.push_back(a[i++]);
while (j < n2) arr3.push_back(b[j++]);

//Find the median:


int n = n1 + n2;
if (n % 2 == 1) {
return (double)arr3[n / 2];
}

double median = ((double)arr3[n / 2] + (double)arr3[(n / 2) - 1]) / 2.0;


return median;
}

int main()
{
vector<int> a = {1, 4, 7, 10, 12};
vector<int> b = {2, 3, 6, 15};
cout << "The median of two sorted array is " << fixed << setprecision(1)
<< median(a, b) << '\n';
}
62.Minimise Maximum Distance between Gas Stations
Problem Statement: You are given a sorted array ‘arr’ of length ‘n’, which contains
positive integer positions of ‘n’ gas stations on the X-axis. You are also given an
integer ‘k’. You have to place ‘k’ new gas stations on the X-axis. You can place
them anywhere on the non-negative side of the X-axis, even on non-integer
positions. Let ‘dist’ be the maximum value of the distance between adjacent gas
stations after adding k new gas stations.
Find the minimum value of ‘dist’.

#include <bits/stdc++.h>
using namespace std;

long double minimiseMaxDistance(vector<int> &arr, int k) {


int n = arr.size(); //size of array.
vector<int> howMany(n - 1, 0);

//Pick and place k gas stations:


for (int gasStations = 1; gasStations <= k; gasStations++) {
//Find the maximum section
//and insert the gas station:
long double maxSection = -1;
int maxInd = -1;
for (int i = 0; i < n - 1; i++) {
long double diff = arr[i + 1] - arr[i];
long double sectionLength =
diff / (long double)(howMany[i] + 1);
if (sectionLength > maxSection) {
maxSection = sectionLength;
maxInd = i;
}
}
//insert the current gas station:
howMany[maxInd]++;
}

//Find the maximum distance i.e. the answer:


long double maxAns = -1;
for (int i = 0; i < n - 1; i++) {
long double diff = arr[i + 1] - arr[i];
long double sectionLength =
diff / (long double)(howMany[i] + 1);
maxAns = max(maxAns, sectionLength);
}
return maxAns;
}

int main()
{
vector<int> arr = {1, 2, 3, 4, 5};
int k = 4;
long double ans = minimiseMaxDistance(arr, k);
cout << "The answer is: " << ans << "\n";
return 0;
}
63.next_permutation : find next lexicographically greater permutation
Problem Statement: Given an array Arr[] of integers, rearrange the numbers of the
given array into the lexicographically next greater permutation of numbers.

If such an arrangement is not possible, it must rearrange to the lowest possible


order (i.e., sorted in ascending order).

#include<iostream>
#include<vector>
#include<algorithm>

using namespace std;

int main() {
int arr[] = {1,3,2};

next_permutation(arr,arr+3);//using in-built function of C++

cout<<arr[0]<<" "<<arr[1]<<" "<<arr[2];

return 0;
}
60.3 Sum : Find triplets that add up to a zero
Problem Statement: Given an array of N integers, your task is to find unique
triplets that add up to give a sum of zero. In short, you need to return an array
of all the unique triplets [arr[a], arr[b], arr[c]] such that i!=j, j!=k, k!=i, and
their sum is equal to zero.

#include <bits/stdc++.h>
using namespace std;

vector<vector<int>> triplet(int n, vector<int> &arr) {


set<vector<int>> st;

// check all possible triplets:


for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
for (int k = j + 1; k < n; k++) {
if (arr[i] + arr[j] + arr[k] == 0) {
vector<int> temp = {arr[i], arr[j], arr[k]};
sort(temp.begin(), temp.end());
st.insert(temp);
}
}
}
}

//store the set elements in the answer:


vector<vector<int>> ans(st.begin(), st.end());
return ans;
}

int main()
{
vector<int> arr = { -1, 0, 1, 2, -1, -4};
int n = arr.size();
vector<vector<int>> ans = triplet(n, arr);
for (auto it : ans) {
cout << "[";
for (auto i : it) {
cout << i << " ";
}
cout << "] ";
}
cout << "\n";
return 0;
}
61.Kadane’s Algorithm : Maximum Subarray Sum in an Array
Problem Statement: Given an integer array arr, find the contiguous subarray
(containing at least one number) which
has the largest sum and returns its sum and prints the subarray.

#include <bits/stdc++.h>
using namespace std;

int maxSubarraySum(int arr[], int n) {


int maxi = INT_MIN; // maximum sum

for (int i = 0; i < n; i++) {


for (int j = i; j < n; j++) {
// subarray = arr[i.....j]
int sum = 0;

//add all the elements of subarray:


for (int k = i; k <= j; k++) {
sum += arr[k];
}

maxi = max(maxi, sum);


}
}

return maxi;
}

int main()
{
int arr[] = { -2, 1, -3, 4, -1, 2, 1, -5, 4};
int n = sizeof(arr) / sizeof(arr[0]);
int maxSum = maxSubarraySum(arr, n);
cout << "The maximum subarray sum is: " << maxSum << endl;
return 0;
}
60.55
Majority Elements(>N/3 times) | Find the elements that appears more than N/3 times
in the array
Problem Statement: Given an array of N integers. Find the elements that appear more
than N/3 times in the array. If no such element exists, return an empty vector.

Pre-requisite: Majority Element(>N/2 times)

#include <bits/stdc++.h>
using namespace std;

vector<int> majorityElement(vector<int> v) {
int n = v.size(); //size of the array
vector<int> ls; // list of answers

for (int i = 0; i < n; i++) {


//selected element is v[i]:
// Checking if v[i] is not already
// a part of the answer:
if (ls.size() == 0 || ls[0] != v[i]) {
int cnt = 0;
for (int j = 0; j < n; j++) {
// counting the frequency of v[i]
if (v[j] == v[i]) {
cnt++;
}
}

// check if frquency is greater than n/3:


if (cnt > (n / 3))
ls.push_back(v[i]);
}

if (ls.size() == 2) break;
}

return ls;
}

int main()
{
vector<int> arr = {11, 33, 33, 11, 33, 11};
vector<int> ans = majorityElement(arr);
cout << "The majority elements are: ";
for (auto it : ans)
cout << it << " ";
cout << "\n";
return 0;
}

60.Count the number of subarrays with given xor K


Problem Statement: Given an array of integers A and an integer B. Find the total
number of subarrays having bitwise XOR of all elements equal to k.

#include <bits/stdc++.h>
using namespace std;

int subarraysWithXorK(vector<int> a, int k) {


int n = a.size(); //size of the given array.
int cnt = 0;

// Step 1: Generating subarrays:


for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
//step 2:calculate XOR of all
// elements:
int xorr = 0;
for (int K = i; K <= j; K++) {
xorr = xorr ^ a[K];
}

// step 3:check XOR and count:


if (xorr == k) cnt++;
}
}
return cnt;
}

int main()
{
vector<int> a = {4, 2, 2, 6, 4};
int k = 6;
int ans = subarraysWithXorK(a, k);
cout << "The number of subarrays with XOR k is: "
<< ans << "\n";
return 0;
}
61.Find the repeating and missing numbers
Problem Statement: You are given a read-only array of N integers with values also
in the range [1, N] both inclusive. Each integer appears exactly once except A
which appears twice and B which is missing. The task is to find the repeating and
missing numbers A and B where A repeats twice and B is missing.

#include <bits/stdc++.h>
using namespace std;

vector<int> findMissingRepeatingNumbers(vector<int> a) {
int n = a.size(); // size of the array
int repeating = -1, missing = -1;

//Find the repeating and missing number:


for (int i = 1; i <= n; i++) {
//Count the occurrences:
int cnt = 0;
for (int j = 0; j < n; j++) {
if (a[j] == i) cnt++;
}

if (cnt == 2) repeating = i;
else if (cnt == 0) missing = i;

if (repeating != -1 && missing != -1)


break;
}
return {repeating, missing};
}

int main()
{
vector<int> a = {3, 1, 2, 5, 4, 6, 7, 5};
vector<int> ans = findMissingRepeatingNumbers(a);
cout << "The repeating and missing numbers are: {"
<< ans[0] << ", " << ans[1] << "}\n";
return 0;
}

70.Count inversions in an array


Problem Statement: Given an array of N integers, count the inversion of the array
(using merge-sort).

What is an inversion of an array? Definition: for all i & j < size of array, if i <
j then you have to find pair (A[i],A[j]) such that A[j] < A[i].

#include <bits/stdc++.h>
using namespace std;

int numberOfInversions(vector<int>&a, int n) {

// Count the number of pairs:


int cnt = 0;
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
if (a[i] > a[j]) cnt++;
}
}
return cnt;
}

int main()
{
vector<int> a = {5, 4, 3, 2, 1};
int n = 5;
int cnt = numberOfInversions(a, n);
cout << "The number of inversions is: "
<< cnt << endl;
return 0;
}
70.Maximum Product Subarray in an Array
Problem Statement: Given an array that contains both negative and positive
integers, find the maximum product subarray.

#include<bits/stdc++.h>
using namespace std;

int maxProductSubArray(vector<int>& nums) {


int result = INT_MIN;
for(int i=0;i<nums.size()-1;i++) {
for(int j=i+1;j<nums.size();j++) {
int prod = 1;
for(int k=i;k<=j;k++)
prod *= nums[k];
result = max(result,prod);
}
}
return result;
}
int main() {
vector<int> nums = {1,2,-3,0,-4,-5};
cout<<"The maximum product subarray: "<<maxProductSubArray(nums);
return 0;
}

You might also like