Data Structure Interview Questions For Freshers
Data Structure Interview Questions For Freshers
A data structure is a mechanical or logical way that data is organized within a program. The
organization of data is what determines how a program performs. There are many types of data
structures, each with its own uses. When designing code, we need to pay particular attention to the
way data is structured. If data isn't stored efficiently or correctly structured, then the overall
performance of the code will be reduced.
Data structures serve a number of important functions in a program. They ensure that each line of
code performs its function correctly and efficiently, they help the programmer identify and fix
problems with his/her code, and they help to create a clear and organized code base.
Decision Making
Genetics
Image Processing
coder.s
Blockchain
Compiler Design
A variable is stored in memory based on the amount of memory that is needed. Following
are the steps followed to store a variable:
Using concepts like dynamic allocation ensures high efficiency and that the storage units can
be accessed based on requirements in real-time.
5. Can you explain the difference between file structure and storage structure?
File Structure: Representation of data into secondary or auxiliary memory say any device
such as a hard disk or pen drives that stores data which remains intact until manually deleted
is known as a file structure representation.
Storage Structure: In this type, data is stored in the main memory i.e RAM, and is deleted
once the function that uses this data gets completely executed.
The difference is that the storage structure has data stored in the memory of the computer system,
whereas the file structure has the data stored in the auxiliary memory.
Linear Data Structure: A data structure that includes data elements arranged sequentially or
linearly, where each element is connected to its previous and next nearest elements, is
referred to as a linear data structure. Arrays and linked lists are two examples of linear data
structures.
Non-Linear Data Structure: Non-linear data structures are data structures in which data
elements are not arranged linearly or sequentially. We cannot walk through all elements in
one pass in a non-linear data structure, as in a linear data structure. Trees and graphs are
two examples of non-linear data structures.
coder.s
7. What is a stack data structure? What are the applications of stack?
A stack is a data structure that is used to represent the state of an application at a particular point in
time. The stack consists of a series of items that are added to the top of the stack and then removed
from the top. It is a linear data structure that follows a particular order in which operations are
performed. LIFO (Last In First Out) or FILO (First In Last Out) are two possible orders. A stack consists
of a sequence of items. The element that's added last will come out first, a real-life example might be
a stack of clothes on top of each other. When we remove the cloth that was previously on top, we
can say that the cloth that was added last comes out first.
first.
Reversing a string
Parenthesis matching
Some of the main operations provided in the stack data structure are:
push: This adds an item to the top of the stack. The overflow condition occurs if the stack is
full.
pop: This removes the top item of the stack. Underflow condition occurs if the stack is
empty.
coder.s
isEmpty: This returns true if the stack is empty else false.
A queue is a linear data structure that allows users to store items in a list in a systematic manner. The
items are added to the queue at the rear end until they are full, at which point they are removed
from the queue from the front. Queues are commonly used in situations where the users want to
hold items for a long period of time, such as during a checkout process. A good example of a queue is
any queue of customers for a resource where the first consumer is served first.
Operating system: job scheduling operations, Disk scheduling, CPU scheduling etc.
enqueue: This adds an element to the rear end of the queue. Overflow conditions occur if
the queue is full.
dequeue: This removes an element from the front end of the queue. Underflow conditions
occur if the queue is empty.
rear: This returns the rear end element without removing it.
coder.s
Stack Queue
Stack is a linear data structure where data is Queue is a linear data structure where data is ended
added and removed from the top. at the rear end and removed from the front.
Delete operation in Stack is known as pop. Delete operation in Queue is known as dequeue.
Only one pointer is available for both Two pointers are available for addition and deletion:
addition and deletion: top() front() and rear()
A queue can be implemented using two stacks. Let q be the queue andstack1 and stack2 be the 2
stacks for implementing q. We know that stack supports push, pop, and peek operations and using
these operations, we need to emulate the operations of the queue - enqueue and dequeue. Hence,
queue q can be implemented in two methods (Both the methods use auxillary space complexity of
O(n)):
Here, the oldest element is always at the top of stack1 which ensures dequeue operation
occurs in O(1) time complexity.
Pseudocode:
coder.s
o Enqueue: Here time complexity will be O(n)
enqueue(q, data):
deQueue(q):
Here, for enqueue operation, the new element is pushed at the top of stack1. Here, the
enqueue operation time complexity is O(1).
In dequeue, if stack2 is empty, all elements from stack1 are moved to stack2 and top
of stack2 is the result. Basically, reversing the list by pushing to a stack and returning the first
enqueued element. This operation of pushing all elements to a new stack takes O(n)
complexity.
Pseudocode:
enqueue(q, data):
dequeue(q):
If stack2 is empty:
A stack can be implemented using two queues. We know that a queue supports enqueue
and dequeue operations. Using these operations, we need to develop push, pop operations.
Let stack be ‘s’ and queues used to implement be ‘q1’ and ‘q2’. Then, stack ‘s’ can be
implemented in two ways:
coder.s
1. By making push operation costly:
This method ensures that the newly entered element is always at the front of ‘q1’ so that
pop operation just dequeues from ‘q1’.
‘q2’ is used as auxillary queue to put every new element in front of ‘q1’ while ensuring pop
happens in O(1) complexity.
Pseudocode:
push(s, data):
Enqueue data to q2
pop(s):
In pop operation, all the elements from q1 except the last remaining element, are pushed to
q2 if it is empty. That last element remaining of q1 is dequeued and returned.
Pseudocode:
push(s,data):
Enqueue data to q1
pop(s):
Step1: Dequeue every elements except the last element from q1 and enqueue to q2.
Step2: Dequeue the last item of q1, the dequeued item is stored in result variable.
Step3: Swap the names of q1 and q2 (for getting updated data after dequeue)
14. What is array data structure? What are the applications of arrays?
An array data structure is a data structure that is used to store data in a way that is efficient and easy
to access. It is similar to a list in that it stores data in a sequence. However, an array data structure
differs from a list in that it can hold much more data than a list can. An array data structure is created
coder.s
by combining several arrays together. Each array is then given a unique identifier, and each array’s
data is stored in the order in which they are created.
Array data structures are commonly used in databases and other computer systems to store large
amounts of data efficiently. They are also useful for storing information that is frequently accessed,
such as large amounts of text or images.
Two-dimensional array: A two-dimensional array is a tabular array that includes rows and
columns and stores data. An M × N two-dimensional array is created by grouping M rows and
N columns into N columns and rows.
coder.s
Three-dimensional array: A three-dimensional array is a grid that has rows, columns, and
depth as a third dimension. It comprises a cube with rows, columns, and depth as a third
dimension. The three-dimensional array has three subscripts for a position in a particular
row, column, and depth. Depth (dimension or layer) is the first index, row index is the second
index, and column index is the third index.
coder.s
16. What is a linked list data structure? What are the applications for the Linked list?
A linked list can be thought of as a series of linked nodes (or items) that are connected by links (or
paths). Each link represents an entry into the linked list, and each entry points to the next node in
the sequence. The order in which nodes are added to the list is determined by the order in which
they are created.
Stack, Queue, binary trees, and graphs are implemented using linked lists.
coder.s
Round robin scheduling for operating system tasks.
1. Singly Linked List: A singly linked list is a data structure that is used to store multiple items. The
items are linked together using the key. The key is used to identify the item and is usually a unique
identifier. In a singly linked list, each item is stored in a separate node. The node can be a single
object or it can be a collection of objects. When an item is added to the list, the node is updated and
the new item is added to the end of the list. When an item is removed from the list, the node that
contains the removed item is deleted and its place is taken by another node. The key of a singly
linked list can be any type of data structure that can be used to identify an object. For example, it
could be an integer, a string, or even another singly linked list. Singly-linked lists are useful for storing
many different types of data. For example, they are commonly used to store lists of items such as
grocery lists or patient records. They are also useful for storing data that is time sensitive such as
stock market prices or flight schedules.
2. Doubly Linked List: A doubly linked list is a data structure that allows for two-way data access such
that each node in the list points to the next node in the list and also points back to its previous node.
In a doubly linked list, each node can be accessed by its address, and the contents of the node can be
accessed by its index. It's ideal for applications that need to access large amounts of data in a fast
manner. A disadvantage of a doubly linked list is that it is more difficult to maintain than a single-
linked list. In addition, it is more difficult to add and remove nodes than in a single-linked list.
3. Circular Linked List: A circular linked list is a unidirectional linked list where each node points to its
next node and the last node points back to the first node, which makes it circular.
coder.s
4. Doubly Circular Linked List: A doubly circular linked list is a linked list where each node points to
its next node and its previous node and the last node points back to the first node and first node’s
previous points to the last node.
5. Header List: A list that contains the header node at the beginning of the list, is called the header-
linked list. This is helpful in calculating some repetitive operations like the number of elements in the
list etc.
An array is a collection of data elements A linked list is a collection of entities known as nodes. The
of the same type. node is divided into two sections: data and address.
It keeps the data elements in a single It stores elements at random, or anywhere in the
memory. memory.
coder.s
Arrays Linked Lists
The memory size of an array is fixed and The memory size of a linked list is allocated during
cannot be changed during runtime. runtime.
Operations like insertion and deletion Operations like insertion and deletion are faster in the
take longer time in an array. linked list.
Asymptotic analysis of an algorithm defines the run-time performance as per its mathematical
boundations. Asymptotic analysis helps us articulate the best case(Omega Notation, Ω), average
case(Theta Notation, θ), and worst case(Big Oh Notation, Ο) performance of an algorithm.
Hashmap is a data structure that uses an implementation of a hash table data structure which allows
access to data in constant time (O(1)) complexity if you have the key.
21. What is the requirement for an object to be used as key or value in HashMap?
The key or value object that gets used in the hashmap must
implement equals() and hashcode() method.
The hash code is used when inserting the key object into the map and the equals method is
used when trying to retrieve a value from the map.
The java.util.HashMap class in Java uses the approach of chaining to handle collisions. In
chaining, if the new values with the same key are attempted to be pushed, then these values
are stored in a linked list stored in a bucket of the key as a chain along with the existing
value.
In the worst-case scenario, it can happen that all keys might have the same hashcode, which
will result in the hash table turning into a linked list. In this case, searching a value will take
O(n) complexity as opposed to O(1) time due to the nature of the linked list. Hence, care has
to be taken while selecting hashing algorithm.
23. What is the time complexity of basic operations get() and put() in HashMap class?
The time complexity is O(1) assuming that the hash function used in the hash map distributes
elements uniformly among the buckets.
coder.s
1. What is binary tree data structure? What are the applications for binary trees?
A binary tree is a data structure that is used to organize data in a way that allows for efficient
retrieval and manipulation. It is a data structure that uses two nodes, called leaves and nodes, to
represent the data. The leaves represent the data and the nodes represent the relationships
between the leaves. Each node has two children, called siblings, and each child has one parent. The
parent is the node that is closest to the root of the tree. When a node is deleted from the tree, it is
deleted from both its child and its parent.
It's widely used in computer networks for storing routing table information.
Decision Trees.
Expression Evaluation.
Database indices.
2. What is binary search tree data structure? What are the applications for binary search trees?
A binary search tree is a data structure that stores items in sorted order. In a binary search tree, each
node stores a key and a value. The key is used to access the item and the value is used to determine
whether the item is present or not. The key can be any type of value such as an integer, floating point
number, character string, or even a combination of these types. The value can be any type of items
such as an integer, floating point number, character string, or even a combination of these types.
coder.s
When a node is added to the tree, its key is used to access the item stored at that node. When a
node is removed from the tree, its key is used to access the item stored at that node.
A binary search tree is a special type of binary tree that has a specific order of elements in it. It has
three basic qualities:
All elements in the left subtree of a node should have a value less than or equal to the parent
node's value, and
All elements in the right subtree of a node should have a value greater than or equal to the
parent node's value.
Both the left and right subtrees must be binary search trees too.
Tree traversal is the process of visiting all the nodes of a tree. Since the root (head) is the first node
and all nodes are connected via edges (or links) we always start with that node. There are three ways
which we use to traverse a tree −
1. Inorder Traversal:
Algorithm:
coder.s
o Step 2. Visit the root.
if (root == null)
return;
printInorderTraversal(root.left);
printInorderTraversal(root.right);
Uses: In binary search trees (BST), inorder traversal gives nodes in ascending order.
2. Preorder Traversal:
Algorithm:
if (root == null)
return;
printPreorderTraversal(root.left);
coder.s
//then traverse to the right subtree
printPreorderTraversal(root.right);
Uses:
3. Postorder Traversal:
Algorithm:
if (root == null)
return;
printPostorderTraversal(root.left);
printPostorderTraversal(root.right);
Uses:
coder.s
Inorder Traversal => Left, Root, Right : [4, 2, 5, 1, 3]
4. What is a deque data structure and its types? What are the applications for deque?
A deque can be thought of as an array of items, but with one important difference: Instead of
pushing and popping items off the end to make room, deques are designed to allow items to be
inserted at either end. This property makes deques well-suited for performing tasks such as keeping
track of inventory, scheduling tasks, or handling large amounts of data.
coder.s
There are two types of deque:
Input Restricted Deque: Insertion operations are performed at only one end while deletion
is performed at both ends in the input restricted queue.
Output Restricted Deque: Deletion operations are performed at only one end while
insertion is performed at both ends in the output restricted queue.
It can be used as both stack and queue, as it supports all the operations for both data
structures.
5. What are some key operations performed on the Deque data structure?
coder.s
6. What is a priority queue? What are the applications for priority queue?
Priority Queue is an abstract data type that is similar to a queue in that each element is assigned a
priority value. The order in which elements in a priority queue are served is determined by their
priority (i.e., the order in which they are removed). If the elements have the same priority, they are
served in the order they appear in the queue.
Used in graph algorithms like Dijkstra, Prim’s Minimum spanning tree etc.
The following table contains an asymptotic analysis of different implementations of a priority queue:
coder.s
Operations peek insert delete
8. What is graph data structure and its representations? What are the applications for graphs?
A graph is a type of non-linear data structure made up of nodes and edges. The nodes are also
known as vertices, and edges are lines or arcs that connect any two nodes in the graph.
1. Adjacency Matrix: Adjacency Matrix is a two-dimensional array with the dimensions V x V, where
V is the number of vertices in a graph. Representation is simpler to implement and adhere to. It takes
O(1) time to remove an edge. Queries such as whether there is an edge from vertex 'u' to vertex 'v'
are efficient and can be completed in O(1).
coder.s
One of the cons of this representation is that even if the graph is sparse (has fewer edges), it takes up
the same amount of space. Adding a vertex takes O(V^2). It also takes O(V) time to compute all of a
vertex's neighbours, which is not very efficient.
2. Adjacency List: In this method, each Node holds a list of Nodes that are directly connected to that
vertex. Each node at the end of the list is connected with null values to indicate that it is the last
node in the list. This saves space O(|V|+|E|). In the worst-case scenario, a graph can have C(V, 2)
edges, consuming O(V^2) space. It is simpler to add a vertex. It takes the least amount of time to
compute all of a vertex's neighbours.
One of the cons of this representation is that queries such as "is there an edge from vertex u to
vertex v?" are inefficient and take O (V) in the worst case.
9. What is the difference between the Breadth First Search (BFS) and Depth First Search (DFS)?
coder.s
Breadth First Search (BFS) Depth First Search (DFS)
It stands for “Breadth First Search” It stands for “Depth First Search”
We walk through all nodes on the same DFS begins at the root node and proceeds as far as
level before passing to the next level in possible through the nodes until we reach the node
BFS. with no unvisited nearby nodes.
When compared to DFS, BFS is slower. When compared to BFS, DFS is faster.
BFS performs better when the target is DFS performs better when the target is far from the
close to the source. source.
Nodes that have been traversed multiple When there are no more nodes to visit, the visited
times are removed from the queue. nodes are added to the stack and then removed.
10. What is AVL tree data structure, its operations, and its rotations? What are the applications for
AVL trees?
coder.s
AVL trees are height balancing binary search trees named after their inventors Adelson, Velski, and
Landis. The AVL tree compares the heights of the left and right subtrees and ensures that the
difference is less than one. This distinction is known as the Balance Factor.
Insertion: Insertion in an AVL tree is done in the same way that it is done in a binary search
tree. However, it may cause a violation in the AVL tree property, requiring the tree to be
balanced. Rotations can be used to balance the tree.
Deletion: Deletion can also be performed in the same manner as in a binary search tree.
Because deletion can disrupt the tree's balance, various types of rotations are used to
rebalance it.
An AVL tree can balance itself by performing the four rotations listed below:
Left rotation: When a node is inserted into the right subtree of the right subtree and the tree
becomes unbalanced, we perform a single left rotation.
coder.s
Right rotation: If a node is inserted in the left subtree of the left subtree, the AVL tree may
become unbalanced. The tree then requires right rotation.
Left-Right rotation: The RR rotation is performed first on the subtree, followed by the LL
rotation on the entire tree.
Right-Left rotation: The LL rotation is performed first on the subtree, followed by the RR
rotation on the entire tree.
Following are some real-time applications for AVL tree data structure:
AVL trees are typically used for in-memory sets and dictionaries.
AVL trees are also widely used in database applications where there are fewer insertions and
deletions but frequent data lookups are required.
Apart from database applications, it is used in applications that require improved searching.
11. What is a B-tree data structure? What are the applications for B-trees?
The B Tree is a type of m-way tree that is commonly used for disc access. A B-Tree with order m can
only have m-1 keys and m children. One of the primary reasons for using a B tree is its ability to store
a large number of keys in a single node as well as large key values while keeping the tree's height
relatively small.
The term minimum degree 't' describes a B-Tree. The value of t is determined by the size of
the disc block.
Except for root, every node must have at least t-1 keys. The root must contain at least one
key.
All nodes (including root) can have no more than 2*t - 1 keys.
The number of children of a node is equal to its key count plus one.
A node's keys are sorted in ascending order. The child of two keys k1 and k2 contains all keys
between k1 and k2.
In contrast to Binary Search Tree, B-Tree grows and shrinks from the root.
coder.s
Using a B tree, you can search for data in a data set in significantly less time.
A segment Tree is a binary tree that is used to store intervals or segments. The Segment Tree is made
up of nodes that represent intervals. Segment Tree is used when there are multiple range queries on
an array and changes to array elements.
Following are key operations performed on the Segment tree data structure:
Building Tree: In this step, we create the structure and initialize the segment tree variable.
Updating the Tree: In this step, we change the tree by updating the array value at a point or
over an interval.
Querying Tree: This operation can be used to run a range query on the array.
Used to efficiently list all pairs of intersecting rectangles from a list of rectangles in the plane.
The segment tree has become popular for use in pattern recognition and image processing.
Computational geometry
The word "Trie" is an abbreviation for "retrieval." Trie is a data structure that stores a set of strings as
a sorted tree. Each node has the same number of pointers as the number of alphabet characters. It
coder.s
can look up a word in the dictionary by using its prefix. Assuming that all strings are formed from the
letters 'a' to 'z' in the English alphabet, each trie node can have a maximum of 26 points.
Trie is also referred to as the digital tree or the prefix tree. The key to which a node is connected is
determined by its position in the Trie. Trie allows us to insert and find strings in O(L) time, where L is
the length of a single word. This is clearly faster than BST. Because of how it is implemented, this is
also faster than Hashing. There is no need to compute a hash function. There is no need to handle
collisions (like we do in open addressing and separate chaining)
Another benefit of Trie is that we can easily print all words in alphabetical order, which is not easy
with hashing. Trie can also perform prefix search (or auto-complete) efficiently.
The main disadvantage of tries is that they require a large amount of memory to store the strings.
We have an excessive number of node pointers for each node
Genome Analysis
Data Analytics
Browser History
coder.s
Spell Checker
Red Black Trees are a type of self-balancing binary search tree. Rudolf Bayer invented it in 1972 and
dubbed it "symmetric binary B-trees."
A red-black tree is a Binary tree in which each node has a colour attribute, either red or black. By
comparing the node colours on any simple path from the root to a leaf, red-black trees ensure that
no path is more than twice as long as any other, ensuring that the tree is generally balanced.
Red-black trees are similar to binary trees in that they both store their data in two's complementary
binary formats. However, red-black trees have one important advantage over binary trees: they are
faster to access. Because red-black trees are so fast to access, they are often used to store large
amounts of data.
Red-black trees can be used to store any type of data that can be represented as a set of values.
coder.s
There is the same number of black nodes on every path from a node to any of its
descendant's NULL nodes.
Following are some real-time applications for the Red-Black Tree data structure:
The majority of self-balancing BST library functions in C++ or Java use Red-Black Trees.
It is also used to reduce time complexity in the K-mean clustering algorithm in machine
learning.
MySQL also employs the Red-Black tree for table indexes in order to reduce searching and
insertion time.
15. Which data structures are used for implementing LRU cache?
LRU cache or Least Recently Used cache allows quick identification of an element that hasn’t been
put to use for the longest time by organizing items in order of use. In order to achieve this, two data
structures are used:
Queue – This is implemented using a doubly-linked list. The maximum size of the queue is
determined by the cache size, i.e by the total number of available frames. The least recently
used pages will be near the front end of the queue whereas the most recently used pages
will be towards the rear end of the queue.
Hashmap – Hashmap stores the page number as the key along with the address of the
corresponding queue node as the value.
Heap is a special tree-based non-linear data structure in which the tree is a complete binary tree. A
binary tree is said to be complete if all levels are completely filled except possibly the last level and
the last level has all elements as left as possible. Heaps are of two types:
Max-Heap:
o In a Max-Heap the data element present at the root node must be the greatest
among all the data elements present in the tree.
coder.s
o This property should be recursively true for all sub-trees of that binary tree.
Min-Heap:
o In a Min-Heap the data element present at the root node must be the smallest (or
minimum) among all the data elements present in the tree.
o This property should be recursively true for all sub-trees of that binary tree.
Input: {1, 1, 1, 2, 3, 3, 6, 6, 7}
Output: {1, 2, 3, 6, 7}
Explanation: The given input has only 1,2,3,6, and 7 as unique elements, hence the output
only lists them out.
#include <bits/stdc++.h>
class Solution{
public:
int index=0;
for(int i=1;i<n;i++) {
a[index]=a[i];
return index+1;
};
coder.s
int main()
int T;
cin>>T;
while(T--)
int N;
cin>>N;
int a[N];
for(int i=0;i<N;i++)
cin>>a[i];
Solution ob;
int n = ob.removeDuplicates(a,N);
for(int i=0;i<n;i++)
cout<<a[i]<<" ";
cout<<endl;
Input:
Output: [1, 3, 2, 4, 5, 6, 8, 7]
coder.s
Explanation: Zigzag Traversal first iterates the given level of the tree from left to right and
then the next level as the right to the level.
// Tree Node
struct Node {
int data;
Node* left;
Node* right;
};
stack<Node*> st1;
stack<Node*> st2;
vector<int> result;
st1.push(root);
while(!st1.empty() || !st2.empty()){
while(!st1.empty()){
Node* temp=st1.top();
st1.pop();
result.push_back(temp->data);
if(temp->left)
st2.push(temp->left);
coder.s
if(temp->right)
st2.push(temp->right);
while(!st2.empty()){
Node* temp=st2.top();
st2.pop();
result.push_back(temp->data);
if(temp->right)
st1.push(temp->right);
if(temp->left)
st1.push(temp->left);
return result;
Input: 0->1->0->2->1->0->2->1
Output: 0->0->0->1->1->1->2->2
Explanation: All 0’s will come first then 1s and then 2s. This can be done in O(n) time by
counting the occurrences of all three and rearranging them in the linked list.
struct Node {
int data;
Node *left;
Node *right;
coder.s
//function take the head of the linked list as a parameter
if(head==NULL)
return;
else
Node *temp=head;
Node *temp1=head;
int count0=0,count1=0,count2=0;
while(temp!=NULL)
if(temp->data==0)
count0++;
else if(temp->data==1)
count1++;
else
count2++;
temp=temp->next;
while(count0!=0)
temp1->data=0;
temp1=temp1->next;
count0--;
coder.s
while(count1!=0)
temp1->data=1;
temp1=temp1->next;
count1--;
while(count2!=0)
temp1->data=2;
temp1=temp1->next;
count2--;
Input: n = 4, e = 4 , 0 1, 1 2, 2 3, 3 1
Output: Yes
From the above representation, we can see that there exists a cycle: 1→2→3→1
int ans=0;
visited[i]=1;
rec[i]=1;
for(auto x : adj[i]){
coder.s
if(x!=parent) {
if(rec[x])
return 1;
ans=dfs(v,adj,visited,rec,x,i);
if(ans)
return 1;
rec[i]=0;
return 0;
vector<int> visited(v,0),rec(v,0);
int ans=0;
for(int i=0;i<v;i++){
if(visited[i]==0)
ans=dfs(v,adj,visited,rec,i,-1);
if(ans)
return 1;
return 0;
Input: a+b*(c^d)
Output: abcd^*+
int prec(char c)
coder.s
if (c == '^')
return 3;
return 2;
return 1;
else
return -1;
public:
string infixToPostfix(string s) {
stack<char> st; // For stack operations, we are using C++ built in stack
string result;
char c = s[i];
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')
result += c;
else if (c == '(')
st.push('(');
coder.s
// until an '(' is encountered.
else if (c == ')') {
result += st.top();
st.pop();
st.pop();
// If an operator is scanned
else {
while (!st.empty()
break;
else {
result += st.top();
st.pop();
st.push(c);
while (!st.empty()) {
result += st.top();
st.pop();
return result;
coder.s
}
6. Write a function to find the maximum for each and every contiguous subarray of size k.
Output: {3, 3, 4, 5, 5, 5, 6}
Explanation: In the first subarray of size 3: {1,2,3}, the value 3 is maximum, similarly for all
such subarrays for size 3.
int i=0,j=0;
deque<int> dq;
dq.push_front(i++);
while(i<k)
while(!dq.empty()&&arr[dq.back()]<=arr[i])
dq.pop_back();
dq.push_back(i++);
vector<int> ans;
while(i<n)
ans.push_back(arr[dq.front()]);
while(!dq.empty()&&j>=dq.front())
dq.pop_front();
j++;
while(!dq.empty()&&arr[dq.back()]<=arr[i])
dq.pop_back();
coder.s
dq.push_back(i++);
ans.push_back(arr[dq.front()]);
return ans;
Input:
First BST
/ \
5 9
Second BST
/ \
3 12
Output: 3 4 5 6 7 9 12
void inorder(Node*root,vector<int>&v){
if(root==NULL)
return;
inorder(root->left,v);
v.push_back(root->data);
inorder(root->right,v);
vector<int> merge(vector<int>v1,vector<int>v2){
vector<int>v;
int n1=v1.size(),n2=v2.size(),i=0,j=0;
coder.s
while(i<n1&&j<n2){
if(v1[i]>v2[j]){
v.push_back(v2[j]);
j++;
else{
v.push_back(v1[i]);
i++;
while(i<n1){
v.push_back(v1[i]);
i++;
while(j<n2){
v.push_back(v2[j]);
j++;
return v;
vector<int>v1,v2;
inorder(root1,v1);
inorder(root2,v2);
return merge(v1,v2);
Space Complexity: O(height of the first tree + height of the second tree)
Input:
coder.s
{{1, 1, 1, 0, 0},
{0, 1, 0, 0, 1},
{1, 0, 1, 1, 0},
{0, 1, 0, 0, 1},
{1, 1, 1, 0, 0}}
Output:
{{1, 1, 1, 0, 0},
{0, 1, 0, 0, 1},
{1, 0, 1, 1, 0}}
set<vector<int>> st;
vector<vector<int>> v;
vector<int> v1;
v1.push_back(M[i][j]);
if(st.count(v1) == 0) {
v.push_back(v1);
st.insert(v1);
return v;
coder.s
Input: arr = [1, 6, 2, 3, 2, 1], k = 12
Output: 11
int ans=0;
int pdt=1;
int left=0,right=0;
while(right<=nums.size()-1){
pdt*=nums[right];
pdt/=nums[left];
left++;
if(right-left>=0)
right++;
return ans;
10. Find the subsequence of length 3 with the highest product from a sequence of non-negative
integers, with the elements in increasing order.
The three increasing elements of the given arrays are 10, 11, and 12, which form a three-size
subsequence with the highest product.
set<int> s;
coder.s
long long largestOnLeft[n];
for(int i=0;i<n;i++)
s.insert(a[i]);
auto it=s.lower_bound(a[i]);
if(it==s.begin())
largestOnLeft[i]=-1;
continue;
it--;
largestOnLeft[i]=*it;
int m=0;
vector<int> result(3);
result[0]=-1;
for(int i=n-1;i>=0;i--)
if(a[i]>=m){
m=a[i];}
else
if(largestOnLeft[i] !=-1)
if(largestOnLeft[i]*a[i]*m >p)
p=largestOnLeft[i]*a[i]*m;
result[0]=largestOnLeft[i];
result[1]=a[i];
result[2]=m;
coder.s
}
return v;
Input: 8<->10<->1<->7<->6
Output: 1<->6<->7<->8<->10
class Solution{
public:
Node*temp = h;
Node*tt = l;
Node*first = l;
while(tt != h){
swap(first->data, tt->data);
first = first->next;
tt = tt -> next;
return first;
};
coder.s
void _quickSort(struct Node* l, struct Node *h)
Solution ob;
_quickSort(l, p->prev);
_quickSort(p->next, h);
_quickSort(head, h);
Time Complexity: O(n^2) in the worst case when the list is already sorted. O(nlog(n)) in the
best and average case.
12. Write a function to connect nodes at the same level of a binary tree
Input: 100
/ \
13 15
/ \ \
14 1 20
/ \
/ \ \
coder.s
14 -> 1 -> 20 -> NULL
class Solution
public:
queue<Node *> q;
queue<int> l;
q.push(p);
l.push(0);
while(!q.empty())
Node *temp=q.front();
int level=l.front();
q.pop();
l.pop();
m[level].push_back(temp);
if(temp->left!=NULL)
q.push(temp->left);
l.push(level+1);
if(temp->right!=NULL)
q.push(temp->right);
l.push(level+1);
coder.s
{
for(int i=0;i<temp1.size()-1;i++)
temp1[i]->nextRight=temp1[i+1];
temp1[temp1.size()-1]->nextRight=NULL;
};
13. Write a function to find number of structurally unique binary trees are possible
Input: N = 3
1 3 3 21
\ / / / \ \
3 2 1 1 3 2
/ / \ \
2 1 2 3
class Solution
public:
if (k > n - k)
k = n - k;
coder.s
{
res *= (n - i);
res /= (i + 1);
return res;
// return 2nCn/(n+1)
return C/(n+1);
return countOfUniqueBinarySearchTrees;
};
coder.s
class LRUCache
private:
class node_t {
public:
int key;
int value;
node_t * next;
node_t * prev;
};
int cap;
node_t head;
node->next->prev = node->prev;
node->prev->next = node->next;
node->next = head.next;
node->prev = &head;
head.next = node;
node->next->prev = node;
public:
//Constructor for initializing the cache capacity with the given value.
// code here
head.prev = &head;
coder.s
head.next = &head;
if(it==tbl.end())
return -1;
remove_node(it->second);
add_node(it->second);
return it->second->value;
if(it!=tbl.end())
remove_node(it->second);
add_node(it->second);
it->second->value = value;
else {
node->key = key;
node->value = value;
add_node(node);
coder.s
tbl[key] = node;
if(tbl.size()>cap) {
tbl.erase(old_node->key);
remove_node(old_node);
delete old_node;
};
15. Write a function to determine whether duplicate elements in a given array are within a given
distance of each other.
Output: True
class Solution {
public:
unordered_set<int> myset;
if (myset.find(arr[i]) != myset.end())
return true;
coder.s
// Add this item to hashset
myset.insert(arr[i]);
if (i >= range)
myset.erase(arr[i-range]);
return false;
};
16. Write a recursive function to calculate the height of a binary tree in Java.
Consider that every node of a tree represents a class called Node as given below:
int data;
Node left;
Node right;
if (node == null)
else
//use the larger among the left and right height and plus 1 (for the root)
coder.s
}
if (root ==null)
return 0;
else
count += countNodes(root.left);
count += countNodes(root.right);
return count;
The main idea to solve this problem is to traverse the tree in pre order manner and pass the
level information along with it. If the level is visited for the first time, then we store the
information of the current node and the current level in the hashmap. Basically, we are
getting the left view by noting the first node of every level.
At the end of traversal, we can get the solution by just traversing the map.
Consider the following tree as example for finding the left view:
import java.util.HashMap;
class Node
int data;
Node(int data) {
coder.s
this.data = data;
public static void leftViewUtil(Node root, int level, HashMap<Integer, Integer> map)
if (root == null) {
return;
if (!map.containsKey(level)) {
map.put(level, root.data);
// traverse the tree and find out the first nodes of each level
leftViewUtil(root, 1, map);
coder.s
// iterate through the HashMap and print the left view
leftView(root);
19. Given an m x n 2D grid map of '1’s which represents land and '0’s that represents water return
the number of islands (surrounded by water and formed by connecting adjacent lands in 2
directions - vertically or horizontally).
Assume that the boundary cases - which are all four edges of the grid are surrounded by water.
Constraints are:
m == grid.length
n == grid[i].length
1 <= m, n <= 300
grid[i][j] can only be ‘0’ or ‘1’.
Example:
Input: grid = [
[“1” , “1” , “1” , “0” , “0”],
[“1” , “1” , “0” , “0” , “0”],
[“0” , “0” , “1” , “0” , “1”],
coder.s
[“0” , “0” , “0” , “1” , “1”]
]
Output: 3
class InterviewBit {
if(grid==null || grid.length==0||grid[0].length==0)
return 0;
int m = grid.length;
int n = grid[0].length;
int count=0;
if(grid[i][j]=='1'){
count++;
mergeIslands(grid, i, j);
return count;
int m=grid.length;
int n=grid[0].length;
if(i<0||i>=m||j<0||j>=n||grid[i][j]!='1')
return;
coder.s
grid[i][j]='X';
mergeIslands(grid, i, j-1);
mergeIslands(grid, i, j+1);
Topological sorting is a linear ordering of vertices such that for every directed edge ij, vertex i
comes before j in the ordering.
Applications:
4. data serialization
// V - total vertices
void topologicalSort()
visited[j] = false;
coder.s
}
// Call the util function starting from all vertices one by one
if (visited[i] == false)
Stack<Integer> stack)
visited[v] = true;
Integer i;
Iterator<Integer> it = graph.get(v).iterator();
while (it.hasNext()) {
i = it.next();
if (!visited[i])
stack.push(new Integer(v));
coder.s