Data Structures and algorithms interview questions

¡Supera tus tareas y exámenes ahora con Quizwiz!

What is a Queue, how it is different from stack and how is it implemented?

Queue is a linear structure which follows the order is First In First Out (FIFO) to access elements. Mainly the following are basic operations on queue: Enqueue, Dequeue, Front, Rear The difference between stacks and queues is in removing. In a stack we remove the item the most recently added; in a queue, we remove the item the least recently added. Both Queues and Stacks can be implemented using Arrays and Linked Lists.

What are linear and non linear data Structures?

Linear: A data structure is said to be linear if its elements form a sequence or a linear list. Examples: Array. Linked List, Stacks and Queues Non-Linear: A data structure is said to be non-linear if traversal of nodes is nonlinear in nature. Example: Graph and Trees.

5. Merge Sort

MergeSort(arr[], l, r) If r > l 1. Find the middle point to divide the array into two halves: middle m = (l+r)/2 2. Call mergeSort for first half: Call mergeSort(arr, l, m) 3. Call mergeSort for second half: Call mergeSort(arr, m+1, r) 4. Merge the two halves sorted in step 2 and 3: Call merge(arr, l, m, r)

9. Merge Sort For Linked Lists

MergeSort(headRef) 1) If head is NULL or there is only one element in the Linked List then return. 2) Else divide the linked list into two halves. FrontBackSplit(head, &a, &b); /* a and b are two halves */ 3) Sort the two halves a and b. MergeSort(a); MergeSort(b); 4) Merge the sorted a and b (using SortedMerge() discussed here) and update the head pointer using headRef. *headRef = SortedMerge(a, b);

What is a Data Structure?

A data structure is a way of organizing the data so that the data can be used efficiently

Explain Breadth First Search (BFS)?

First move horizontally and visit all the nodes of the current layer Move to the next layer. To avoid processing a node more than once, we use a boolean visited array.

2. Maximum Path Sum in a Binary Tree

For each node there can be four ways that the max path goes through the node: 1. Node only 2. Max path through Left Child + Node 3. Max path through Right Child + Node 4. Max path through Left Child + Node + Max path through Right Child The idea is to keep trace of four paths and pick up the max one in the end. An important thing to note is, root of every subtree need to return maximum path sum such that at most one child of root is involved. This is needed for parent function call. In below code, this sum is stored in 'max_single' and returned by the recursive function.

Which data structures are used for BFS and DFS of a graph?

Queue is used for BFS Stack is used for DFS. DFS can also be implemented using recursion (Note that recursion also uses function call stack).

5. Find the element that appears once Given an array where every element occurs three times, except one element which occurs only once. Find the element that occurs once. Expected time complexity is O(n) and O(1) extra space.

The idea is to use bitwise operators for a solution that is O(n) time and uses O(1) extra space. The solution is not easy like other XOR based solutions, because all elements appear odd number of times here. The idea is taken from here. Run a loop for all elements in array. At the end of every iteration, maintain following two values. ones: The bits that have appeared 1st time or 4th time or 7th time .. etc. twos: The bits that have appeared 2nd time or 5th time or 8th time .. etc. Finally, we return the value of 'ones'

2. Delete a given node in Linked List (under given constraints)

We explicitly handle the case when node to be deleted is first node, we copy the data of next node to head and delete the next node. The cases when deleted node is not the head node can be handled normally by finding the previous node and changing next of previous node. Following is C implementation.

Explain a full binary tree?

a binary tree T is full if each node is either a leaf or possesses exactly two child nodes

Why array based representation for Binary Heap?

array based representation is space efficient. If the parent node is stored at index I, the left child can be calculated by 2 * I + 1 and right child by 2 * I + 2 (assuming the indexing starts at 0).

What is a perfect binary tree?

is a binary tree in which all interior nodes have two children and all leaves have the same depth or same level.[18]

Explain a complete binary tree?

is a binary tree in which every level, except possibly the last, is completely filled, and all nodes are as far left as possible

9. 0-1 Knapsack Problem

# A Dynamic Programming based Python Program for 0-1 Knapsack problem # Returns the maximum value that can be put in a knapsack of capacity W def knapSack(W, wt, val, n): K = [[0 for x in range(W+1)] for x in range(n+1)] # Build table K[][] in bottom up manner for i in range(n+1): for w in range(W+1): if i==0 or w==0: K[i][w] = 0 elif wt[i-1] <= w: K[i][w] = max(val[i-1] + K[i-1][w-wt[i-1]], K[i-1][w]) else: K[i][w] = K[i-1][w] return K[n][W]

3. Compare two strings represented as linked lists

# Traverse both lists. Stop when either end of linked # list is reached or current characters don't watch while(list1 and list2 and list1.c == list2.c): list1 = list1.next list2 = list2.next # If both lists are not empty, compare mismatching # characters if(list1 and list2): return 1 if list1.c > list2.c else -1 # If either of the two lists has reached end if (list1 and not list2): return 1 if (list2 and not list1): return -1 return 0

10. Select A Random Node from A Singly Linked List

(1) Initialize result as first node result = head->key (2) Initialize n = 2 (3) Now one by one consider all nodes from 2nd node onward. (3.a) Generate a random number from 0 to n-1. Let the generated random number is j. (3.b) If j is equal to 0 (we could choose other fixed number between 0 to n-1), then replace result with current node. (3.c) n = n+1 (3.d) current = current->next

7. Quick Sort

/* low --> Starting index, high --> Ending index */ quickSort(arr[], low, high) { if (low < high) { /* pi is partitioning index, arr[pi] is now at right place */ pi = partition(arr, low, high); quickSort(arr, low, pi - 1); // Before pi quickSort(arr, pi + 1, high); // After pi } } /* This function takes last element as pivot, places the pivot element at its correct position in sorted array, and places all smaller (smaller than pivot) to left of pivot and all greater elements to right of pivot */ partition (arr[], low, high) { // pivot (Element to be placed at right position) pivot = arr[high]; i = (low - 1) // Index of smaller element for (j = low; j <= high- 1; j++) { // If current element is smaller than or // equal to pivot if (arr[j] <= pivot) { i++; // increment index of smaller element swap arr[i] and arr[j] } } swap arr[i + 1] and arr[high]) return (i + 1) }

4. Insertion Sort

// Sort an arr[] of size n insertionSort(arr, n) Loop from i = 1 to n-1. ......a) Pick element arr[i] and insert it into sorted sequence arr[0...i-1] <like inserting a card in a deck>

8. Interpolation Search

// The idea of formula is to return higher value of pos // when element to be searched is closer to arr[hi]. And // smaller value when closer to arr[lo] pos = lo + [ (x-arr[lo])*(hi-lo) / (arr[hi]-arr[Lo]) ] arr[] ==> Array where elements need to be searched x ==> Element to be searched lo ==> Starting index in arr[] hi ==> Ending index in arr[] Step1: In a loop, calculate the value of "pos" using the probe position formula. Step2: If it is a match, return the index of the item, and exit. Step3: If the item is less than arr[pos], calculate the probe position of the left sub-array. Otherwise calculate the same in the right sub-array. Step4: Repeat until a match is found or the sub-array reduces to zero.

4. Add Two Numbers Represented By Linked Lists

1) Calculate sizes of given two linked lists. 2) If sizes are same, then calculate sum using recursion. Hold all nodes in recursion call stack till the rightmost node, calculate sum of rightmost nodes and forward carry to left side. 3) If size is not same, then follow below steps: ....a) Calculate difference of sizes of two linked lists. Let the difference be diff ....b) Move diff nodes ahead in the bigger linked list. Now use step 2 to calculate sum of smaller list and right sub-list (of same size) of larger list. Also, store the carry of this sum. ....c) Calculate sum of the carry (calculated in previous step) with the remaining left sub-list of larger list. Nodes of this sum are added at the beginning of sum list obtained previous step.

Explain does Minimum Spanning tree **Prim** ?

1) Create a set mstSet that keeps track of vertices already included in MST. 2) Assign a key value to all vertices in the input graph. Initialize all key values as INFINITE. Assign key value as 0 for the first vertex so that it is picked first. 3) While mstSet doesn't include all vertices ....a) Pick a vertex u which is not there in mstSet and has minimum key value. ....b) Include u to mstSet. ....c) Update key value of all adjacent vertices of u. To update the key values, iterate through all adjacent vertices. For every adjacent vertex v, if weight of edge u-v is less than the previous key value of v, update the key value as weight of u-v

10. Bridges in a Graph

1) For every edge (u, v), do following .....a) Remove (u, v) from graph .....b) See if the graph remains connected (We can either use BFS or DFS) .....c) Add (u, v) back to the graph. Time complexity of above method is O(E*(V+E))

10. Given a sorted array and a number x, find the pair in array whose sum is closest to x

1) Initialize a variable diff as infinite (Diff is used to store the difference between pair and x). We need to find the minimum diff. 2) Initialize two index variables l and r in the given sorted array. (a) Initialize first to the leftmost index: l = 0 (b) Initialize second the rightmost index: r = n-1 3) Loop while l < r. (a) If abs(arr[l] + arr[r] - sum) < diff then update diff and result (b) Else if(arr[l] + arr[r] < sum ) then l++ (c) Else r--

Longest Common Subsequence?

1) Optimal Substructure: Let the input sequences be X[0..m-1] and Y[0..n-1] of lengths m and n respectively. And let L(X[0..m-1], Y[0..n-1]) be the length of LCS of the two sequences X and Y. Following is the recursive definition of L(X[0..m-1], Y[0..n-1]). If last characters of both sequences match (or X[m-1] == Y[n-1]) then L(X[0..m-1], Y[0..n-1]) = 1 + L(X[0..m-2], Y[0..n-2]) If last characters of both sequences do not match (or X[m-1] != Y[n-1]) then L(X[0..m-1], Y[0..n-1]) = MAX ( L(X[0..m-2], Y[0..n-1]), L(X[0..m-1], Y[0..n-2])

10 most common problems Dynamic Programming?

1. Longest Common Subsequence 2. Longest Increasing Subsequence 3. Edit Distance 4. Minimum Partition 5. Ways to Cover a Distance 6. Longest Path In Matrix 7. Subset Sum Problem 8. Optimal Strategy for a Game 9. 0-1 Knapsack Problem 10. Boolean Parenthesization Problem

Sorting And Searching

1. Binary Search 2. Search an element in a sorted and rotated array 3. Bubble Sort 4. Insertion Sort 5. Merge Sort 6. Heap Sort (Binary Heap) 7. Quick Sort 8. Interpolation Search 9. Find Kth Smallest/Largest Element In Unsorted Array 10. Given a sorted array and a number x, find the pair in array whose sum is closest to x

Top 10 graph problems?

1. Breadth First Search (BFS) 2. Depth First Search (DFS) 3. Shortest Path from source to all vertices **Dijkstra** 4. Shortest Path from every vertex to every other vertex **Floyd Warshall** 5. To detect cycle in a Graph **Union Find** 6. Minimum Spanning tree **Prim** 7. Minimum Spanning tree **Kruskal** 8. Topological Sort 9. Boggle (Find all possible words in a board of characters) 10. Bridges in a Graph

6. Heap Sort (Binary Heap)

1. Build a max heap from the input data. 2. At this point, the largest item is stored at the root of the heap. Replace it with the last item of the heap followed by reducing the size of heap by 1. Finally, heapify the root of tree. 3. Repeat above steps while size of heap is greater than 1.

10 top Tree / Binary Search questions?

1. Find Minimum Depth of a Binary Tree 2. Maximum Path Sum in a Binary Tree 3. Check if a given array can represent Preorder Traversal of Binary Search Tree 4. Check whether a binary tree is a full binary tree or not 5. Bottom View Binary Tree 6. Print Nodes in Top View of Binary Tree 7. Remove nodes on root to leaf paths of length < K 8. Lowest Common Ancestor in a Binary Search Tree 9. Check if a binary tree is subtree of another binary tree 10. Reverse alternate levels of a perfect binary tree

Top 10 algorithms for linked lists?

1. Insertion of a node in Linked List (On the basis of some constraints) 2. Delete a given node in Linked List (under given constraints) 3. Compare two strings represented as linked lists 4. Add Two Numbers Represented By Linked Lists 5. Merge A Linked List Into Another Linked List At Alternate Positions 6. Reverse A List In Groups Of Given Size 7. Union And Intersection Of 2 Linked Lists 8. Detect And Remove Loop In A Linked List 9. Merge Sort For Linked Lists 10. Select A Random Node from A Singly Linked List

BIT Manipulation top 10

1. Maximum Subarray XOR 2. Magic Number 3. Sum of bit differences among all pairs 4. Swap All Odds And Even Bits 5. Find the element that appears once 6. Binary representation of a given number 7. Count total set bits in all numbers from 1 to n 8. Rotate bits of a number 9. Count number of bits to be flipped to convert A to B 10. Find Next Sparse Number

String / Array top 10

1. Reverse an array without affecting special characters 2. All Possible Palindromic Partitions 3. Count triplets with sum smaller than a given value 4. Convert array into Zig-Zag fashion 5. Generate all possible sorted arrays from alternate elements of two given sorted arrays 6. Pythagorean Triplet in an array 7. Length of the largest subarray with contiguous elements 8. Find the smallest positive integer value that cannot be represented as sum of any subset of a given array 9. Smallest subarray with sum greater than a given value 10. Stock Buy Sell to Maximize Profit

Explain Minimum Spanning tree **Kruskal** ?

1. Sort all the edges in non-decreasing order of their weight. 2. Pick the smallest edge. Check if it forms a cycle with the spanning tree formed so far. If cycle is not formed, include this edge. Else, discard it. 3. Repeat step#2 until there are (V-1) edges in the spanning tree.

3. Check if a given array can represent Preorder Traversal of Binary Search Tree

A Simple Solution is to do following for every node pre[i] starting from first one. 1) Find the first greater value on right side of current node. Let the index of this node be j. Return true if following conditions hold. Else return false (i) All values after the above found greater value are greater than current node. (ii) Recursive calls for the subarrays pre[i+1..j-1] and pre[j+1..n-1] also return true. Time Complexity of the above solution is O(n2) An Efficient Solution can solve this problem in O(n) time. The idea is to use a stack. This problem is similar to Next (or closest) Greater Element problem. Here we find next greater element and after finding next greater, if we find a smaller element, then return false. 1) Create an empty stack. 2) Initialize root as INT_MIN. 3) Do following for every element pre[i] a) If pre[i] is smaller than current root, return false. b) Keep removing elements from stack while pre[i] is greater then stack top. Make the last removed item as new root (to be compared next). At this point, pre[i] is greater than the removed root (That is why if we see a smaller element in step a), we return false) c) push pre[i] to stack (All elements in stack are in decreasing order)

4. Convert array into Zig-Zag fashion

A Simple Solution is to first sort the array. After sorting, exclude the first element, swap the remaining elements in pairs. (i.e. keep arr[0] as it is, swap arr[1] and arr[2], swap arr[3] and arr[4], and so on). Time complexity is O(nlogn) since we need to sort the array first. We can convert in O(n) time using an Efficient Approach. The idea is to use modified one pass of bubble sort. Maintain a flag for representing which order(i.e. < or >) currently we need. If the current two elements are not in that order then swap those elements otherwise not.

3. Count triplets with sum smaller than a given value

A Simple Solution is to run three loops to consider all triplets one by one. For every triplet, compare the sums and increment count if triplet sum is smaller than given sum. better solution: 1) Sort the input array in increasing order. 2) Initialize result as 0. 3) Run a loop from i = 0 to n-2. An iteration of this loop finds all triplets with arr[i] as first element. a) Initialize other two elements as corner elements of subarray arr[i+1..n-1], i.e., j = i+1 and k = n-1 b) Move j and k toward each other until they meet, i.e., while (j < k) (i) if (arr[i] + arr[j] + arr[k] >= sum), then do k-- // Else for current i and j, there can (k-j) possible third elements // that satisfy the constraint. (ii) Else Do ans += (k - j) followed by j++

9. Find Kth Smallest/Largest Element In Unsorted Array

A Simple Solution is to sort the given array using a O(nlogn) sorting algorithm like Merge Sort, Heap Sort, etc and return the element at index k-1 in the sorted array. Time Complexity of this solution is O(nLogn). Method 3 (Using Max-Heap) We can also use Max Heap for finding the k'th smallest element. Following is algorithm. 1) Build a Max-Heap MH of the first k elements (arr[0] to arr[k-1]) of the given array. O(k) 2) For each element, after the k'th element (arr[k] to arr[n-1]), compare it with root of MH. ......a) If the element is less than the root then make it root and call heapify for MH ......b) Else ignore it. // The step 2 is O((n-k)*logk) 3) Finally, root of the MH is the kth smallest element. Time complexity of this solution is O(k + (n-k)*Logk) The following is C++ implementation of above algorithm

8. Find the smallest positive integer value that cannot be represented as sum of any subset of a given array

A Simple Solution is to start from value 1 and check all values one by one if they can sum to values in the given array. This solution is very inefficient as it reduces to subset sum problem which is a well known NP Complete Problem. We can solve this problem in O(n) time using a simple loop. Let the input array be arr[0..n-1]. We initialize the result as 1 (smallest possible outcome) and traverse the given array. Let the smallest element that cannot be represented by elements at indexes from 0 to (i-1) be 'res', there are following two possibilities when we consider element at index i: 1) We decide that 'res' is the final result: If arr[i] is greater than 'res', then we found the gap which is 'res' because the elements after arr[i] are also going to be greater than 'res'. 2) The value of 'res' is incremented after considering arr[i]: The value of 'res' is incremented by arr[i] (why? If elements from 0 to (i-1) can represent 1 to 'res-1', then elements from 0 to i can represent from 1 to 'res + arr[i] - 1' be adding 'arr[i]' to all subsets that represent 1 to 'res')

1. Maximum Subarray XOR

A Simple Solution is to use two loops to find XOR of all subarrays and return the maximum. ^ 1) Create an empty Trie. Every node of Trie is going to contain two children, for 0 and 1 value of bit. 2) Initialize pre_xor = 0 and insert into the Trie. 3) Initialize result = minus infinite 4) Traverse the given array and do following for every array element arr[i]. a) pre_xor = pre_xor ^ arr[i] pre_xor now contains xor of elements from arr[0] to arr[i]. b) Query the maximum xor value ending with arr[i] from Trie. c) Update result if the value obtained in step 4.b is more than current value of result.

What is a Linked List and What are its types?

A linked list is a linear data structure (like arrays) where each element is a separate object. Each element (that is node) of a list is comprising of two items - the data and a reference to the next node.Types of Linked List : Singly Linked List : In this type of linked list, every node stores address or reference of next node in list and the last node has next address or reference as NULL. For example 1->2->3->4->NULL Doubly Linked List : Here, here are two references associated with each node, One of the reference points to the next node and one to the previous node. Eg. NULL<-1<->2<->3->NULL Circular Linked List : Circular linked list is a linked list where all nodes are connected to form a circle. There is no NULL at the end. A circular linked list can be a singly circular linked list or doubly circular linked list. Eg. 1->2->3->1 [The next pointer of last node is pointing to the first]

How to implement a queue using stack?

A queue can be implemented using two stacks. Let queue to be implemented be q and stacks used to implement q be stack1 and stack2. q can be implemented in two ways: Method 1 (By making enQueue operation costly) Method 2 (By making deQueue operation costly) See Implement Queue using Stacks

How to implement a stack using queue?

A stack can be implemented using two queues. Let stack to be implemented be 's' and queues used to implement be 'q1' and 'q2'. Stack 's' can be implemented in two ways: Method 1 (By making push operation costly) Method 2 (By making pop operation costly) See Implement Stack using Queues

6. Reverse A List In Groups Of Given Size

Algorithm: reverse(head, k) 1) Reverse the first sub-list of size k. While reversing keep track of the next node and previous node. Let the pointer to the next node be next and pointer to the previous node be prev. See this post for reversing a linked list. 2) head->next = reverse(next, k) /* Recursively call for rest of the list and link the two sub-lists */ 3) return prev /* prev becomes the new head of the list (see the diagrams of iterative method of this post) */

3. Sum of bit differences among all pairs

An Efficient Solution can solve this problem in O(n) time using the fact that all numbers are represented using 32 bits (or some fixed number of bits). The idea is to count differences at individual bit positions. We traverse from 0 to 31 and count numbers with i'th bit set. Let this count be 'count'. There would be "n-count" numbers with i'th bit not set. So count of differences at i'th bit would be "count * (n-count) * 2".

3. Bubble Sort

Bubble Sort is the simplest sorting algorithm that works by repeatedly swapping the adjacent elements if they are in wrong order.

Explain a binary heap?

Complete Binary Tree where items are stored in a special order such that value in a parent node is greater(or smaller) than the values in its two children nodes. The former is called as max heap and the latter is called min heap. The heap can be represented by binary tree or array.

Can doubly linked be implemented using a single pointer variable in every node?

Doubly linked list can be implemented using a single pointer. See XOR Linked List - A Memory Efficient Doubly Linked List

1. Insertion of a node in Linked List (On the basis of some constraints)

If Linked list is empty then make the node as head and return it. 2) If value of the node to be inserted is smaller than value of head node, then insert the node at start and make it head. 3) In a loop, find the appropriate node after which the input node (let 9) is to be inserted. To find the appropriate node start from head, keep moving until you reach a node GN (10 in the below diagram) who's value is greater than the input node. The node just before GN is the appropriate node (7). 4) Insert the node (9) after the appropriate node (7) found in step 3.

How to check if a given Binary Tree is BST or not?

If inorder traversal of a binary tree is sorted, then the binary tree is BST. The idea is to simply do inorder traversal and while traversing keep track of previous key value. If current key value is greater, then continue, else return false. See A program to check if a binary tree is BST or not for more details.

7. Union And Intersection Of 2 Linked Lists

Intersection (list1, list2) Initialize result list as NULL. Traverse list1 and look for its each element in list2, if the element is present in list2, then add the element to result. Union (list1, list2): Initialize result list as NULL. Traverse list1 and add all of its elements to the result. Traverse list2. If an element of list2 is already present in result then do not insert it to result, otherwise insert. This method assumes that there are no duplicates in the given lists.

8. Lowest Common Ancestor in a Binary Search Tree

If we are given a BST where every node has parent pointer, then LCA can be easily determined by traversing up using parent pointer and printing the first intersecting node. We can solve this problem using BST properties. We can recursively traverse the BST from root. The main idea of the solution is, while traversing from top to bottom, the first node n we encounter with value between n1 and n2, i.e., n1 < n < n2 or same as one of the n1 or n2, is LCA of n1 and n2 (assuming that n1 < n2). So just recursively traverse the BST in, if node's value is greater than both n1 and n2 then our LCA lies in left side of the node, if it's is smaller than both n1 and n2, then LCA lies on right side. Otherwise root is LCA (assuming that both n1 and n2 are present in BST) Time complexity of above solution is O(h) where h is height of tree. Also, the above solution requires O(h) extra space in function call stack for recursive function calls. We can avoid extra space using iterative solution.

10. Boolean Parenthesization Problem

If we draw recursion tree of above recursive solution, we can observe that it many overlapping subproblems. Like other dynamic programming problems, it can be solved by filling a table in bottom up manner. Following is C++ implementation of dynamic programming solution.

Topological Sorting vs Depth First Traversal (DFS): ?

In DFS, we print a vertex and then recursively call DFS for its adjacent vertices. In topological sorting, we need to print a vertex before its adjacent vertices.

Explain Topological Sort?

In DFS, we start from a vertex, we first print it and then recursively call DFS for its adjacent vertices. In topological sorting, we use a temporary stack. We don't print the vertex immediately, we first recursively call topological sorting for all its adjacent vertices, then push it to a stack. Finally, print contents of stack. Note that a vertex is pushed to stack only when all of its adjacent vertices (and their adjacent vertices and so on) are already in stack.

What are Infix, prefix, Postfix notations?

Infix notation: X + Y - Operators are written in-between their operands. This is the usual way we write expressions. An expression such as A * ( B + C ) / D Postfix notation (also known as "Reverse Polish notation"): X Y + Operators are written after their operands. The infix expression given above is equivalent to A B C + * D/ Prefix notation (also known as "Polish notation"): + X Y Operators are written before their operands. The expressions given above are equivalent to / * A + B C D

2. Search an element in a sorted and rotated array

Input arr[] = {3, 4, 5, 1, 2} Element to Search = 1 1) Find out pivot point and divide the array in two sub-arrays. (pivot = 2) /*Index of 5*/ 2) Now call binary search for one of the two sub-arrays. (a) If element is greater than 0th element then search in left array (b) Else Search in right array (1 will go in else as 1 < 0th element(3)) 3) If element is found in selected sub-array then return index Else return -1.

What are the various operations that can be performed on different Data Structures?

Insertion − Add a new data item in the given collection of data items. Deletion − Delete an existing data item from the given collection of data items. Traversal − Access each data item exactly once so that it can be processed. Searching − Find out the location of the data item if it exists in the given collection of data items. Sorting − Arranging the data items in some order i.e. in ascending or descending order in case of numerical data and in dictionary order in case of alphanumeric data.

Interpolation Search vs Binary Search

Interpolation Search is an improvement over Binary Search for instances, where the values in a sorted array are uniformly distributed. Binary Search always goes to middle element to check. On the other hand interpolation search may go to different locations according the value of key being searched. For example if the value of key is closer to the last element, interpolation search is likely to start search toward the end side.

8. Rotate bits of a number

Let n is stored using 8 bits. Left rotation of n = 11100101 by 3 makes n = 00101111 (Left shifted by 3 and first 3 bits are put back in last ). If n is stored using 16 bits or 32 bits then left rotation of n (000...11100101) becomes 00..0011100101000. Right rotation of n = 11100101 by 3 makes n = 10111100 (Right shifted by 3 and last 3 bits are put back in first ) if n is stored using 8 bits. If n is stored using 16 bits or 32 bits then right rotation of n (000...11100101) by 3 becomes 101000..0011100.

6. Pythagorean Triplet in an array

Method 1 (Naive) A simple solution is to run three loops, three loops pick three array elements and check if current three elements form a Pythagorean Triplet. Method 2 (Use Sorting) We can solve this in O(n2) time by sorting the array first. 1) Do square of every element in input array. This step takes O(n) time. 2) Sort the squared array in increasing order. This step takes O(nLogn) time. 3) To find a triplet (a, b, c) such that a = b + c, do following. Fix 'a' as last element of sorted array. Now search for pair (b, c) in subarray between first element and 'a'. A pair (b, c) with given sum can be found in O(n) time using meet in middle algorithm discussed in method 1 of this post. If no pair found for current 'a', then move 'a' one position back and repeat step 3.2.

10. Reverse alternate levels of a perfect binary tree

Method 1 (Simple) A simple solution is to do following steps. 1) Access nodes level by level. 2) If current level is odd, then store nodes of this level in an array. 3) Reverse the array and store elements back in tree. Method 2 (Using Two Traversals) Another is to do two inorder traversals. Following are steps to be followed. 1) Traverse the given tree in inorder fashion and store all odd level nodes in an auxiliary array. For the above example given tree, contents of array become {h, i, b, j, k, l, m, c, n, o} 2) Reverse the array. The array now becomes {o, n, c, m, l, k, j, b, i, h} 3) Traverse the tree again inorder fashion. While traversing the tree, one by one take elements from array and store elements from array to every odd level traversed node. For the above example, we traverse 'h' first in above array and replace 'h' with 'o'. Then we traverse 'i' and replace it with n.

5. Bottom View Binary Tree

Method 1 - Using Queue The following are steps to print Bottom View of Binary Tree. 1. We put tree nodes in a queue for the level order traversal. 2. Start with the horizontal distance(hd) 0 of the root node, keep on adding left child to queue along with the horizontal distance as hd-1 and right child as hd+1. 3. Also, use a TreeMap which stores key value pair sorted on key. 4. Every time, we encounter a new horizontal distance or an existing horizontal distance put the node data for the horizontal distance as key. For the first time it will add to the map, next time it will replace the value. This will make sure that the bottom most element for that horizontal distance is present in the map and if you see the tree from beneath that you will see that element. Method 2- Using HashMap() This method is contributed by Ekta Goel. Approach: Create a map like, map where key is the horizontal distance and value is a pair(a, b) where a is the value of the node and b is the height of the node. Perform a pre-order traversal of the tree. If the current node at a horizontal distance of h is the first we've seen, insert it in the map. Otherwise, compare the node with the existing one in map and if the height of the new node is greater, update in the Map.

6. Binary representation of a given number

Method 1: Iterative For any number, we can check whether its 'i'th bit is 0(OFF) or 1(ON) by bitwise ANDing it with "2^i" (2 raise to i). 1) Let us take number 'NUM' and we want to check whether it's 0th bit is ON or OFF bit = 2 ^ 0 (0th bit) if NUM & bit == 1 means 0th bit is ON else 0th bit is OFF 2) Similarly if we want to check whether 5th bit is ON or OFF bit = 2 ^ 5 (5th bit) if NUM & bit == 1 means its 5th bit is ON else 5th bit is OFF. Method 2: Recursive Following is recursive method to print binary representation of 'NUM'. step 1) if NUM > 1 a) push NUM on stack b) recursively call function with 'NUM / 2' step 2) a) pop NUM from stack, divide it by 2 and print it's remainder.

2. All Possible Palindromic Partitions

Note that this problem is different from Palindrome Partitioning Problem, there the task was to find the partitioning with minimum cuts in input string. Here we need to print all possible partitions. The idea is to go through every substring starting from first character, check if it is palindrome. If yes, then add the substring to solution and recur for remaining part. Below is complete algorithm.

Explain Depth First Search (DFS)?

Pick a starting node and push all its adjacent nodes into a stack. Pop a node from stack to select the next node to visit and push all its adjacent nodes into a stack. Repeat this process until the stack is empty. However, ensure that the nodes that are visited are marked. This will prevent you from visiting the same node more than once. If you do not mark the nodes that are visited and you visit the same node more than once, you may end up in an infinite loop.

1. Reverse an array without affecting special characters

Simple Solution: 1) Create a temporary character array say temp[]. 2) Copy alphabetic characters from given array to temp[]. 3) Reverse temp[] using standard string reversal algorithm. 4) Now traverse input string and temp in a single loop. Wherever there is alphabetic character is input string, replace it with current character of temp[]. 1) Let input string be 'str[]' and length of string be 'n' 2) l = 0, r = n-1 3) While l is smaller than r, do following a) If str[l] is not an alphabetic character, do l++ b) Else If str[r] is not an alphabetic character, do r-- c) Else swap str[l] and str[r]

What is Stack and where it can be used?

Stack is a linear data structure which the order LIFO(Last In First Out) or FILO(First In Last Out) for accessing elements. Basic operations of stack are : Push, Pop , Peek Applications of Stack: Infix to Postfix Conversion using Stack Evaluation of Postfix Expression Reverse a String using Stack Implement two stacks in an array Check for balanced parentheses in an expression

4. Swap All Odds And Even Bits

The following solution is based on this observation. The solution assumes that input number is stored using 32 bits. Let the input number be x 1) Get all even bits of x by doing bitwise and of x with 0xAAAAAAAA. The number 0xAAAAAAAA is a 32 bit number with all even bits set as 1 and all odd bits as 0. 2) Get all odd bits of x by doing bitwise and of x with 0x55555555. The number 0x55555555 is a 32 bit number with all odd bits set as 1 and all even bits as 0. 3) Right shift all even bits. 4) Left shift all odd bits. 5) Combine new even and odd bits and return.

7. Remove nodes on root to leaf paths of length < K

The idea here is to use post order traversal of the tree. Before removing a node we need to check that all the children of that node in the shorter path are already removed. There are 2 cases: i) This node becomes a leaf node in which case it needs to be deleted. ii) This node has other child on a path with path length >= k. In that case it needs not to be deleted.

9. Check if a binary tree is subtree of another binary tree

The idea is based on the fact that inorder and preorder/postorder uniquely identify a binary tree. Tree S is a subtree of T if both inorder and preorder traversals of S arew substrings of inorder and preorder traversals of T respectively. Following are detailed steps. 1) Find inorder and preorder traversals of T, store them in two auxiliary arrays inT[] and preT[]. 2) Find inorder and preorder traversals of S, store them in two auxiliary arrays inS[] and preS[]. 3) If inS[] is a subarray of inT[] and preS[] is a subarray preT[], then S is a subtree of T. Else not. We can also use postorder traversal in place of preorder in the above algorithm.

6. Longest Path In Matrix

The idea is simple, we calculate longest path beginning with every cell. Once we have computed longest for all cells, we return maximum of all longest paths. One important observation in this approach is many overlapping subproblems. Therefore this problem can be optimally solved using Dynamic Programming. Below is Dynamic Programming based implementation that uses a lookup table dp[][] to check if a problem is already solved or not.

Explain Boggle (Find all possible words in a board of characters)

The idea is to consider every character as a starting character and find all words starting with it. All words starting from a character can be found using Depth First Traversal. We do depth first traversal starting from every cell. We keep track of visited cells to make sure that a cell is considered only once in a word.

6. Print Nodes in Top View of Binary Tree

The idea is to do something similar to vertical Order Traversal. Like vertical Order Traversal, we need to nodes of same horizontal distance together. We do a level order traversal so that the topmost node at a horizontal node is visited before any other node of same horizontal distance below it. Hashing is used to check if a node at given horizontal distance is seen or not.

5. Merge A Linked List Into Another Linked List At Alternate Positions

The idea is to run a loop while there are available positions in first loop and insert nodes of second list by changing pointers.

1. Find Minimum Depth of a Binary Tree

The idea is to traverse the given Binary Tree. For every node, check if it is a leaf node. If yes, then return 1. If not leaf node then if left subtree is NULL, then recur for right subtree. And if right subtree is NULL, then recur for left subtree. If both left and right subtrees are not NULL, then take the minimum of two heights. Better Solution is to do Level Order Traversal. While doing traversal, returns depth of the first encountered leaf node. Below is implementation of this solution.

5. Generate all possible sorted arrays from alternate elements of two given sorted arrays

The idea is to use recursion. In the recursive function, a flag is passed to indicate whether current element in output should be taken from 'A' or 'B'. Below is C++ implementation.

7. Length of the largest subarray with contiguous elements

The important thing to note in question is, it is given that all elements are distinct. If all elements are distinct, then a subarray has contiguous elements if and only if the difference between maximum and minimum elements in subarray is equal to the difference between last and first indexes of subarray. So the idea is to keep track of minimum and maximum element in every subarray.

How is an Array different from Linked List?

The size of the arrays is fixed, Linked Lists are Dynamic in size. Inserting and deleting a new element in an array of elements is expensive, Whereas both insertion and deletion can easily be done in Linked Lists. Random access is not allowed in Linked Listed. Extra memory space for a pointer is required with each element of the Linked list. Arrays have better cache locality that can make a pretty big difference in performance.

4. Minimum Partition

The task is to divide the set into two parts. We will consider the following factors for dividing it. Let dp[n+1][sum+1] = {1 if some subset from 1st to i'th has a sum equal to j 0 otherwise} i ranges from {1..n} j ranges from {0..(sum of all elements)} So dp[n+1][sum+1] will be 1 if 1) The sum j is achieved including i'th item 2) The sum j is achieved excluding i'th item. Let sum of all the elements be S. To find Minimum sum difference, w have to find j such that Min{sum - j*2 : dp[n][j] == 1 } where j varies from 0 to sum/2 The idea is, sum of S1 is j and it should be closest to sum/2, i.e., 2*j should be closest to sum.

2. Longest Increasing Subsequence?

There is a recursive way, dynamic programming with brute force , and a nlogn version brute force dynamic programming version O(n^2) def lis(arr): n = len(arr) # Declare the list (array) for LIS and initialize LIS # values for all indexes lis = [1]*n # Compute optimized LIS values in bottom up manner for i in range (1 , n): for j in range(0 , i): if arr[i] > arr[j] and lis[i]< lis[j] + 1 : lis[i] = lis[j]+1 # Initialize maximum to 0 to get the maximum of all # LIS maximum = 0 # Pick maximum of all LIS values for i in range(n): maximum = max(maximum , lis[i]) return maximum # end of lis function

7. Count total set bits in all numbers from 1 to n

This needs to be reviewed asked in amazon interview Method 2 (Simple and efficient than Method 1) If we observe bits from rightmost side at distance i than bits get inverted after 2^i position in vertical sequence. for example n = 5; 0 = 0000 1 = 0001 2 = 0010 3 = 0011 4 = 0100 5 = 0101 Observe the right most bit (i = 0) the bits get flipped after (2^0 = 1) Observe the 3nd rightmost bit (i = 2) the bits get flipped after (2^2 = 4) So, We can count bits in vertical fashion such that at i'th right most position bits will be get flipped after 2^i iteration;

4. Check whether a binary tree is a full binary tree or not

To check whether a binary tree is a full binary tree we need to test the following cases:- 1) If a binary tree node is NULL then it is a full binary tree. 2) If a binary tree node does have empty left and right sub-trees, then it is a full binary tree by definition 3) If a binary tree node has left and right sub-trees, then it is a part of a full binary tree by definition. In this case recursively check if the left and right sub-trees are also binary trees themselves. 4) In all other combinations of right and left sub-trees, the binary tree is not a full binary tree.

How To detect cycle in a Graph **Union Find**?

Union-Find Algorithm can be used to check whether an undirected graph contains cycle or not. Note that we have discussed an algorithm to detect cycle. This is another method based on Union-Find. This method assumes that graph doesn't contain any self-loops

1. Binary Search

We basically ignore half of the elements just after one comparison. Compare x with the middle element. If x matches with middle element, we return the mid index. Else If x is greater than the mid element, then x can only lie in right half subarray after the mid element. So we recur for right half. Else (x is smaller) recur for the left half.

7. Subset Sum Problem

We can solve the problem in Pseudo-polynomial time using Dynamic programming. We create a boolean 2D table subset[][] and fill it in bottom up manner. The value of subset[i][j] will be true if there is a subset of set[0..j-1] with sum equal to i., otherwise false. Finally, we return subset[sum][n]

Shortest Path from every vertex to every other vertex **Floyd Warshall*?

We initialize the solution matrix same as the input graph matrix as a first step. Then we update the solution matrix by considering all vertices as an intermediate vertex. The idea is to one by one pick all vertices and update all shortest paths which include the picked vertex as an intermediate vertex in the shortest path. When we pick vertex number k as an intermediate vertex, we already have considered vertices {0, 1, 2, .. k-1} as intermediate vertices. For every pair (i, j) of source and destination vertices respectively, there are two possible cases. 1) k is not an intermediate vertex in shortest path from i to j. We keep the value of dist[i][j] as it is. 2) k is an intermediate vertex in shortest path from i to j. We update the value of dist[i][j] as dist[i][k] + dist[k][j].

8. Detect And Remove Loop In A Linked List

We know that Floyd's Cycle detection algorithm terminates when fast and slow pointers meet at a common point. We also know that this common point is one of the loop nodes (2 or 3 or 4 or 5 in the above diagram). We store the address of this in a pointer variable say ptr2. Then we start from the head of the Linked List and check for nodes one by one if they are reachable from ptr2. When we find a node that is reachable, we know that this node is the starting node of the loop in Linked List and we can get pointer to the previous of this node.

Which Data Structure Should be used for implementing LRU cache?

We use two data structures to implement an LRU Cache. Queue which is implemented using a doubly linked list. The maximum size of the queue will be equal to the total number of frames available (cache size).The most recently used pages will be near front end and least recently pages will be near rear end. A Hash with page number as key and address of the corresponding queue node as value. See How to implement LRU caching scheme? What data structures should be used?

5. Ways to Cover a Distance

class GFG { // Function returns count of ways to cover 'dist' static int printCountDP(int dist) { int[] count = new int[dist+1]; // Initialize base values. There is one way to // cover 0 and 1 distances and two ways to // cover 2 distance count[0] = 1; count[1] = 1; count[2] = 2; // Fill the count array in bottom up manner for (int i=3; i<=dist; i++) count[i] = count[i-1] + count[i-2] + count[i-3]; return count[dist]; } // driver program public static void main (String[] args) { int dist = 4; System.out.println(printCountDP(dist)); } }

3. Edit Distance?

def editDistDP(str1, str2, m, n): # Create a table to store results of subproblems dp = [[0 for x in range(n+1)] for x in range(m+1)] # Fill d[][] in bottom up manner for i in range(m+1): for j in range(n+1): # If first string is empty, only option is to # isnert all characters of second string if i == 0: dp[i][j] = j # Min. operations = j # If second string is empty, only option is to # remove all characters of second string elif j == 0: dp[i][j] = i # Min. operations = i # If last characters are same, ignore last char # and recur for remaining string elif str1[i-1] == str2[j-1]: dp[i][j] = dp[i-1][j-1] # If last character are different, consider all # possibilities and find minimum else: dp[i][j] = 1 + min(dp[i][j-1], # Insert dp[i-1][j], # Remove dp[i-1][j-1]) # Replace return dp[m][n]

10. Stock Buy Sell to Maximize Profit

f we are allowed to buy and sell only once, then we can use following algorithm. Maximum difference between two elements. Here we are allowed to buy and sell multiple times. Following is algorithm for this problem. 1. Find the local minima and store it as starting index. If not exists, return. 2. Find the local maxima. and store it as ending index. If we reach the end, set the end as ending index. 3. Update the solution (Increment count of buy sell pairs) 4. Repeat the above steps if end is not reached. // Program to find best buying and selling days

Pseudo code for Dijkstra algorithm?

function Dijkstra(Graph, source): 2 3 create vertex set Q 4 5 for each vertex v in Graph: // Initialization 6 dist[v] ← INFINITY // Unknown distance from source to v 7 prev[v] ← UNDEFINED // Previous node in optimal path from source 8 add v to Q // All nodes initially in Q (unvisited nodes) 9 10 dist[source] ← 0 // Distance from source to source 11 12 while Q is not empty: 13 u ← vertex in Q with min dist[u] // Node with the least distance 14 // will be selected first 15 remove u from Q 16 17 for each neighbor v of u: // where v is still in Q. 18 alt ← dist[u] + length(u, v) 19 if alt < dist[v]: // A shorter path to v has been found 20 dist[v] ← alt 21 prev[v] ← u 22 23 return dist[], prev[] If we are only interested in a shortest path between vertices source and target, we can terminate the search after line 15 if u = target. Now we can read the shortest path from source to target by reverse iteration: 1 S ← empty sequence 2 u ← target 3 while prev[u] is defined: // Construct the shortest path with a stack S 4 insert u at the beginning of S // Push the vertex onto the stack 5 u ← prev[u] // Traverse from target to source 6 insert u at the beginning of S // Push the source onto the stack

Explain Shortest Path from source to all vertices **Dijkstra** algorithm?

is an algorithm for finding the shortest paths between nodes in a graph, which may represent, for example, road networks. Mark all nodes unvisited. 1) Create a set sptSet (shortest path tree set) that keeps track of vertices included in shortest path tree, i.e., whose minimum distance from source is calculated and finalized. Initially, this set is empty. 2) Assign a distance value to all vertices in the input graph. Initialize all distance values as INFINITE. Assign distance value as 0 for the source vertex so that it is picked first. 3) While sptSet doesn't include all vertices ....a) Pick a vertex u which is not there in sptSetand has minimum distance value. ....b) Include u to sptSet. ....c) Update distance value of all adjacent vertices of u. To update the distance values, iterate through all adjacent vertices. For every adjacent vertex v, if sum of distance value of u (from source) and weight of edge u-v, is less than the distance value of v, then update the distance value of v.

8. Optimal Strategy for a Game

{ // Create a table to store solutions of subproblems int table[][] = new int[n][n]; int gap, i, j, x, y, z; // Fill table using above recursive formula. // Note that the tableis filled in diagonal // fashion (similar to http://goo.gl/PQqoS), // from diagonal elements to table[0][n-1] // which is the result. for (gap = 0; gap < n; ++gap) { for (i = 0, j = gap; j < n; ++i, ++j) { // Here x is value of F(i+2, j), // y is F(i+1, j-1) and z is // F(i, j-2) in above recursive formula x = ((i + 2) <= j) ? table[i + 2][j] : 0; y = ((i + 1) <= (j - 1)) ? table[i +1 ][j - 1] : 0; z = (i <= (j - 2)) ? table[i][j - 2]: 0; table[i][j] = Math.max(arr[i] + Math.min(x, y), arr[j] + Math.min(y, z)); } } return table[0][n - 1]; }


Conjuntos de estudio relacionados

Driver's Ed-Vehicle Requirements

View Set

c and the challenge of secularisation part 1

View Set

BUS. STRAT CHAPTER 4 QUIZ (TEST 1)

View Set

mktg 353 chapter 16 knowledge checks

View Set

schenck v. united states & tinker v. des moines independent community school district

View Set

Endocrinology - Pancreatic Hormones

View Set

Chapter 44: Assessment and Management of Patients with Biliary Disorders

View Set

Anatomy Chapter 15: Special Senses

View Set

Cubed Roots, Square Roots, Irrational and Rational Numbers

View Set