Algorithms Interview Questions PDF
Algorithms Interview Questions PDF
codespaghetti.com/java-algorithms-questions/
Algorithms
Java Algorithm And Data Structure Interview Questions and Programs
Table of Contents:
1/56
Java Quick Sort Interview Questions
This algorithm is quite efficient for large-sized data sets as its average and worst case
complexity are of Ο(n2), where n is the number of items.
ALGORITHM
_# choose pivot_
swap a[1,rand(1,n)]
_# 2-way partition_
k = 1
for i = 2:n, if a[i] < a[1], swap a[++k,i]
swap a[1,k]
_→ invariant: a[1..k-1] < a[k] <= a[k+1..n]_
_# recursive sorts_
sort a[1..k-1]
sort a[k+1,n]
Full Implementation
2/56
package codespaghetti.com;
int i = lowerIndex;
int j = higherIndex;
// calculate pivot number, I am taking pivot as middle index number
int pivot = array[lowerIndex+(higherIndex-lowerIndex)/2];
// Divide into two arrays
while (i <= j) {
/**
* In each iteration, we will identify a number from left side which
* is greater then the pivot value, and also we will identify a number
* from right side which is less then the pivot value. Once the search
* is done, then we exchange both numbers.
*/
while (array[i] < pivot) { i++; } while (array[j] > pivot) {
j--;
}
if (i <= j) {
exchangeNumbers(i, j);
//move index to next position on both sides
i++;
j--;
}
}
// call quickSort() method recursively
if (lowerIndex < j)
quickSort(lowerIndex, j);
if (i < higherIndex)
quickSort(i, higherIndex);
}
The 2-way partitioning code shown above is written for clarity rather than optimal
performance.
It exhibits poor locality, and, critically, exhibits O(n2) time when there are few unique keys.
A more efficient and robust 2-way partitioning method is given in Quicksort is Optimal by
Robert Sedgewick and Jon Bentley.
The robust partitioning produces balanced recursion when there are many values equal to
the pivot, yielding probabilistic guarantees of O(n·lg(n)) time and O(lg(n)) space for all
inputs.
With both sub-sorts performed recursively, quick sort requires O(n) extra space for the
recursion stack in the worst case when recursion is not balanced.
This is exceedingly unlikely to occur, but it can be avoided by sorting the smaller sub-array
recursively first; the second sub-array sort is a tail recursive call, which may be done with
iteration instead.
With this optimization, the algorithm uses O(lg(n)) extra space in the worst case.
Best-case performance O(n log n) (simple partition) or O(n) (three-way partition and equal
keys)
4/56
Worst-case space O(n) auxiliary (naive) O(log n) auxiliary
complexity
It sequentially checks each element of the list for the target value until a match is found or
until all the elements have been searched.
Linear search runs in at worst linear time and makes at most n comparisons, where n is the
length of the list.
Algorithm
Linear Search ( Array A, Value x)
Step 1: Set i to 1
Step 2: if i > n then go to step 7
Step 3: if A[i] = x then go to step 6
Step 4: Set i to i + 1
Step 5: Go to Step 2
Step 6: Print Element x Found at index i and go to step 8
Step 7: Print element not found
Step 8: Exit
Pseudocode
5/56
procedure linear_search (list, value)
end if
end for
end procedure
package codespaghetti.com;
Output:
Key 34 found at index: 6
Key 421 found at index: 2
6/56
Average performance O(n)
import java.io.*;
import java.util.*;
// Constructor
Graph(int v)
{
V = v;
adj = new LinkedList[v];
for (int i=0; i<v; ++i)
adj[i] = new LinkedList();
7/56
}
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
g.DFS();
}
}
Output:
Following is Depth First Traversal
8/56
0 1 2 3
Time Complexity: O(V+E) where V is number of vertices in the graph and E is number
of edges in the graph.
Worst-case {displaystyle O(|V|)} if entire graph is traversed without repetition, O(longest path
space length searched) for implicit graphs without elimination of duplicate nodes
complexity
import java.io.*;
import java.util.*;
// Constructor
Graph(int v)
{
V = v;
adj = new LinkedList[v];
for (int i=0; i<v; ++i)
adj[i] = new LinkedList();
}
while (queue.size() != 0)
{
// Dequeue a vertex from queue and print it
s = queue.poll();
System.out.print(s+" ");
// Driver method to
public static void main(String args[])
{
10/56
Graph g = new Graph(4);
g.addEdge(0, 1);
g.addEdge(0, 2);
g.addEdge(1, 2);
g.addEdge(2, 0);
g.addEdge(2, 3);
g.addEdge(3, 3);
g.BFS(2);
}
}
Output:
Following is Breadth First Traversal (starting from vertex 2)
2 0 3 1
Worst-case performance
For this algorithm to work properly, the data collection should be in the sorted form.
Binary search compares the target value to the middle element of the array, if they are
unequal, the half in which the target cannot lie is eliminated and the search continues on
the remaining half until it is successful or the remaining half is empty.
Pseudocode
The pseudocode of binary search algorithms should look like this −
11/56
Procedure binary_search
A ← sorted array
n ← size of array
x ← value to be searched
Set lowerBound = 1
Set upperBound = n
if A[midPoint] < x
set lowerBound = midPoint + 1
if A[midPoint] > x
set upperBound = midPoint - 1
if A[midPoint] = x
EXIT: x found at location midPoint
end while
end procedure
12/56
package codespaghetti.com;
int start = 0;
int end = inputArr.length - 1;
while (start <= end) {
int mid = (start + end) / 2;
if (key == inputArr[mid]) {
return mid;
}
if (key < inputArr[mid]) {
end = mid - 1;
} else {
start = mid + 1;
}
}
return -1;
}
Output:
Key 14's position: 6
Key 432's position: 4
The minimum depth is the number of nodes along the shortest path from root node down to
the nearest leaf node.
Analysis:
13/56
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.
int minimumDepth()
{
return minimumDepth(root);
}
return Math.min(minimumDepth(root.left),
minimumDepth(root.right)) + 1;
}
14/56
/* Driver program to test above functions */
public static void main(String args[])
{
BinaryTree tree = new BinaryTree();
tree.root = new Node(1);
tree.root.left = new Node(2);
tree.root.right = new Node(3);
tree.root.left.left = new Node(4);
tree.root.left.right = new Node(5);
Output:
Performance:
Time complexity of the solution is O(n) as it traverses the tree only once.
15/56
Example
0 1
2 1
0 2
4 1
16/56
class Vertex { List Adjacents; }
queue.Enqueue(source);
while (!queue.IsEmpty())
{
Vertex current = queue.Dequeue();
while (!adjacents.IsEmpty())
{
Vertex curr = adjacents.First();
queue.Enqueue(curr);
}
return count;
}
17/56
Given a binary tree, find the maximum path sum. The path may start and end at any node in
the tree. Example:
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.
int data;
Node left, right;
class BinaryTree {
18/56
// This function returns overall maximum path sum in 'res'
// And returns max path sum going through root.
int findMaxUtil(Node node, Res res)
{
// Base Case
if (node == null)
return 0;
return max_single;
}
int findMaxSum() {
return findMaxSum(root);
}
// Initialize result
// int res2 = Integer.MIN_VALUE;
Res res = new Res();
res.val = Integer.MIN_VALUE;
Output:
Max path sum is 42
Performance
Given a very large binary number which cannot be stored in a variable, determine the
remainder of the decimal equivalent of the binary number when divided by 3. Generalize to
find the remainder for any number k.
20/56
class Main {
public static void main(String[] args) {
BigInteger num = new
BigInteger("9620680364645634331845386726262609206982068206820281340810801411111793759");
String s = num.toString(2);
System.out.println(s);
x %= k;
for (int i = 0; i < times; i++) {
x = (x * maxValModK) % k;
}
res += x;
res %= k;
times++;
}
return res;
}
}
21/56
public static int getDisCnt(Tree root){
Set uniq = new HashSet<>();
if(root == null){
return 0;
}
return getMaxHelper(root, uniq);
}
Given a binary tree, find the maximum path sum. The path may start and end at any node in
the tree. Example:
22/56
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.
int data;
Node left, right;
class BinaryTree {
// Base Case
if (node == null)
return 0;
return max_single;
}
int findMaxSum() {
return findMaxSum(root);
}
// Initialize result
// int res2 = Integer.MIN_VALUE;
Res res = new Res();
res.val = Integer.MIN_VALUE;
Output:
Max path sum is 42
Performance
24/56
Question: Print Nodes in Top View of Binary Tree.
Top view of a binary tree is the set of nodes visible when the tree is viewed from the top.
Given a binary tree, print the top view of it.
The output nodes can be printed in any order. Expected time complexity is O(n)
Horizontal distance of left child of a node x is equal to horizontal distance of x minus 1, and
that of right child is horizontal distance of x plus 1.
Example
1
/
2 3
/ /
4 5 6 7
Top view of the above binary tree is
4 2 1 3 7
1
/
2 3
6
Top view of the above binary tree is
2 1 3 6
// Constructor
public TreeNode(int key)
{
this.key = key;
left = right = null;
}
}
// Constructors
public Tree() { root = null; }
public Tree(TreeNode n) { root = n; }
26/56
// If this is the first node at its horizontal distance,
// then this node is in top view
if (!set.contains(hd))
{
set.add(hd);
System.out.print(n.key + " ");
}
6*/
TreeNode root = new TreeNode(1);
root.left = new TreeNode(2);
root.right = new TreeNode(3);
root.left.right = new TreeNode(4);
root.left.right.right = new TreeNode(5);
root.left.right.right.right = new TreeNode(6);
Tree t = new Tree(root);
System.out.println("Following are nodes in top view of Binary Tree");
t.printTopView();
}
}
Output
Performance
27/56
Question: You have k lists of sorted integers. Find the
smallest range that includes at least one number from each of
the k lists.
Example:
List 1: [4, 10, 15, 24, 26] List 2: [0, 9, 12, 20] List 3: [5, 18, 22, 30] The smallest range here
would be [20, 24] as it contains 24 from list 1, 20 from list 2, and 22 from list 3.
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.TreeSet;
lists.add(list1);
lists.add(list2);
lists.add(list3);
if (listNoAndEntry.size() == k) {
if (listNoAndEntry.containsKey(minData.listNo))
entries.remove(listNoAndEntry.remove(minData.listNo));
listNoAndEntry.put(minData.listNo, minData);
entries.add(minData);
}
if (listNoAndEntry.size() == k) {
class Result {
public final int startRange, endRange;
29/56
class Data implements Comparable {
public final int data;
public final int listNo;
@Override
public int compareTo(Data o) {
// TODO Auto-generated method stub
return data - o.data;
}
}
Example:
30/56
Given a string S, and an interger K, print "YES" if S is a k-palindrome; otherwise
print "NO".
Constraints:
S has at most 20,000 characters.
0<=k<=30
31/56
Then iterate through that Map and print characters which have appeared more than once.
So you actually need two loops to do the job, the first loop to build the map and second loop
to print characters and counts.
32/56
package codespaghetti.com;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
public class FindDuplicateCharacters{
/*
* Find all duplicate characters in a String and print each of them.
*/
public static void printDuplicateCharacters(String word) {
char[] characters = word.toCharArray();
// build HashMap with character and number of times they appear in String
Map<Character, Integer> charMap = new HashMap<Character, Integer>();
for (Character ch : characters) {
if (charMap.containsKey(ch)) {
charMap.put(ch, charMap.get(ch) + 1);
} else {
charMap.put(ch, 1);
}
}
Output
List of duplicate characters in String 'Programming'
g : 2
r : 2
m : 2
List of duplicate characters in String 'Combination'
n : 2
o : 2
i : 2
List of duplicate characters in String 'Java'
2. By using BufferReader
33/56
package codespaghetti.com;
import java.io.*;
public class CountChar
{
}
Output
a 1 Times
s 3 Times
d 2 Times
f 3 Times
34/56
Given a string, find the longest substring that contains only two unique characters. For
example, given "abcbbbbcccbdddadacb", the longest substring that contains 2 unique
character is "bcbbbbcccb".
In this solution, a hashmap is used to track the unique elements in the map. When a third
character is added to the map, the left pointer needs to move right.
while(map.size()>2){
char t = s.charAt(start);
int count = map.get(t);
if(count>1){
map.put(t, count-1);
}else{
map.remove(t);
}
start++;
}
}
}
return max;
}
Now if this question is extended to be "the longest substring that contains k unique
characters", what should we do?
35/56
public int lengthOfLongestSubstringKDistinct(String s, int k) {
if(k==0 || s==null || s.length()==0)
return 0;
if(s.length()<k)
return s.length();
int maxLen=k;
int left=0;
for(int i=0; i<s.length(); i++){ char c = s.charAt(i); if(map.containsKey(c)){
map.put(c, map.get(c)+1); }else{ map.put(c, 1); } if(map.size()>k){
maxLen=Math.max(maxLen, i-left);
while(map.size()>k){
char fc = s.charAt(left);
if(map.get(fc)==1){
map.remove(fc);
}else{
map.put(fc, map.get(fc)-1);
}
left++;
}
}
return maxLen;
}
Time is O(n).
You are given a string, s, and a list of words, words, that are all of the same length. Find all
starting indices of substring(s) in s that is a concatenation of each word in words exactly
once and without any intervening characters.
Analysis
This problem is similar (almost the same) to Longest Substring Which Contains 2 Unique
Characters.
Since each word in the dictionary has the same length, each of them can be treated as a
36/56
single character.
Java Implementation
37/56
public List findSubstring(String s, String[] words) {
ArrayList result = new ArrayList();
if(s==null||s.length()==0||words==null||words.length==0){
return result;
}
//frequency of words
HashMap<String, Integer> map = new HashMap<String, Integer>();
for(String w: words){
if(map.containsKey(w)){
map.put(w, map.get(w)+1);
}else{
map.put(w, 1);
}
}
count--;
start = start + len;
}
if(count==words.length){
result.add(start); //add to result
return result;
}
38/56
Question: Find the shortest substring from the alphabet "abc".
Given an input string "aabbccba", find the shortest substring from the alphabet "abc".
In the above example, there are these substrings "aabbc", "aabbcc", "ccba" and
"cba". However the shortest substring that contains all the characters in the
alphabet is "cba", so "cba" must be the output.
Other examples:
input = "abbcac", alphabet="abc" Output : shortest substring = "bca".
Full Implementation:
39/56
public class Solution {
public String minWindow(String s, String t) { // s is the string and t is
alphabet
int[] map = new int[256];
int begin=0,end=0; // for substring window
int head = begin; // for getting the output substring
Full Implementation
40/56
public static String longestSubstringUnrepeatedChar(String inputString) {
String longestSoFar = "";
String longestSubstringResult = "";
if (inputString.isEmpty()) {
return "";
}
if (inputString.length() == 1) {
return inputString;
}
Map<Character, Integer> map = new HashMap<Character, Integer>();
for (int i = 0; i < inputString.length(); i++) { char currentCharacter =
inputString.charAt(i); if (longestSoFar.indexOf(currentCharacter) == -1) { if
(!map.containsKey(currentCharacter)) { map.put(currentCharacter, i); } longestSoFar
= longestSoFar + currentCharacter; } else { longestSoFar =
inputString.substring(map.get(currentCharacter) + 1, i + 1);
map.put(currentCharacter, i); } if (longestSoFar.length() >
longestSubstringResult.length()) {
longestSubstringResult = longestSoFar;
}
}
return longestSubstringResult;
}
Full Implementation
41/56
Question: How to Reverse Words in a String in Java?
Problem
You are given a string of words and you are required to write a programme which will
reverse the string
The input string does not contain leading or trailing spaces and the words are always
separated by a single space. For example Given string = "This is a test question". And
after the reversal it should look like this Reversed string = "question test a is This" Could
you do it in-place without allocating extra space?
42/56
public static void main(String args[]) throws FileNotFoundException, IOException {
//original string
if (str.length() < 2) {
return str;
43/56
public static void main(String args[]) throws FileNotFoundException, IOException {
//original string
}
public static String reverse(String str) {
strBuilder.append(strChars[i]);
return strBuilder.toString();
44/56
package codespaghetti.com;
reverse(inputString, i, inputString.length-1);
reverse(inputString, 0, inputString.length-1);
}
Example
Input: "1123". You need to general all valid alphabet codes from this string. Output List aabc
//a = 1, a = 1, b = 2, c = 3 kbc // since k is 11, b = 2, c= 3 alc // a = 1, l = 12, c = 3 aaw // a=
1, a =1, w= 23 kw // k = 11, w = 23 Full Implementation: public Set decode(String prefix,
String code) { Set set = new HashSet(); if (code.length() == 0) { set.add(prefix); return set; }
if (code.charAt(0) == '0') return set; set.addAll(decode(prefix + (char) (code.charAt(0) - '1' +
'a'), code.substring(1))); if (code.length() >= 2 && code.charAt(0) == '1') {
set.addAll(decode( prefix + (char) (10 + code.charAt(1) - '1' + 'a'), code.substring(2))); } if
(code.length() >= 2 && code.charAt(0) == '2' && code.charAt(1) <= '6') { set.addAll(decode(
prefix + (char) (20 + code.charAt(1) - '1' + 'a'), code.substring(2))); } return set; }
strStr() function
Returns the index of the first occurrence of needle in haystack, or -1 if needle is not part of
haystack. Java Solution 1 - Naive
45/56
public int strStr(String haystack, String
needle) {
if(haystack==null || needle==null)
return 0;
if(needle.length() == 0)
return 0;
int m = i;
for(int j=0; j<needle.length(); j++){
if(needle.charAt(j)==haystack.charAt(m)){
if(j==needle.length()-1)
return i;
m++;
}else{
break;
}
}
}
return -1;
}
Java Solution 2 - KMP Check out this article to understand KMP algorithm.
46/56
public int strStr(String haystack, String needle) {
if(haystack==null || needle==null)
return 0;
int h = haystack.length();
int n = needle.length();
if (n > h)
return -1;
if (n == 0)
return 0;
while (i <= h - n) {
int success = 1;
for (int j = 0; j < n; j++) {
if (needle.charAt(0) != haystack.charAt(i)) {
success = 0;
i++;
break;
} else if (needle.charAt(j) != haystack.charAt(i + j)) {
success = 0;
i = i + j - next[j - 1];
break;
}
}
if (success == 1)
return i;
}
return -1;
}
if (needle.charAt(index) == needle.charAt(i)) {
next[i] = next[i - 1] + 1;
} else {
next[i] = 0;
}
}
return next;
}
Write a function that given a List and a pattern returns the matching elements.
Full Implementation;
47/56
package codespaghetti.com;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.List;
import java.util.Queue;
import java.util.stream.Collectors;
if (!Character.isUpperCase(ch.charAt(0)))
{
return false;
}
}
48/56
return false;
}
}
Question: Print all the characters in string only once in a reverse order.
Print all the characters present in the given string only once in a reverse order. Time &
Space complexity should not be more than O(N). e.g.
Full Implementation
System.out.println(reversed);
49/56
s = "some string with repeated characters"
map<char, int> m
for each e in m
print e.value
Full Implementation
int [] ar = {1,16,2,3,3,4,4,8,6,5,4};
for (int i=0; i System.out.println ("key ="+ k + ", No. of time Repeated "+ v) );
50/56
public boolean isIsomorphic(String s, String t) {
if(s==null||t==null)
return false;
if(s.length()!=t.length())
return false;
if(map.containsKey(c1)){
if(map.get(c1)!=c2)// if not consistant with previous ones
return false;
}else{
if(map.containsValue(c2)) //if c2 is already being mapped
return false;
map.put(c1, c2);
}
}
return true;
}
Time is O(n).
Given a string e.g. ABCDAABCD. Shuffle he string so that no two smilar letters together.
E.g. AABC can be shuffled as ABAC.
51/56
void ScrambleString( string &inputString, int iter = 4 )
{
if( iter == 0 )
return;
cout << "Iteration : " << iter << endl;
if( iterateFlag )
{
std::reverse(inputString.begin(), inputString.end());
ScrambleString(inputString, iter );
}
return;
}
package codespaghetti.com;
import java.util.HashSet;
import java.util.Set;
52/56
char dummy=arr[i];
arr[i]=arr[j];
arr[j]=dummy;
return new String(arr);
}
//Generates permutations of string and returns a string if it is found in
dictionary or return ""
public static String wordExists(String s,Set dictionary,int i,int j){
if(i==j){
if(dictionary.contains(s)){
return s;
}
}else{
for(int k=i;k<j;k++){
String found=wordExists(swapStringIndexes(s, i, k),dictionary,i+1,j);
if(dictionary.contains(found)){
return found;
}
}
}
return "";
}
//return sentence if can be formed with the given string or return ""
public static String makeSentence(String s,Set dictionary,String sentenceBuilder){
if(s.isEmpty()){
return sentenceBuilder; //sentenceBuilder;
}else{
for(int i=1;i<=s.length();i++){
String first=s.substring(0,i);
String second=s.substring(i);
String foundWord=wordExists(first, dictionary, 0, i);
if(!foundWord.isEmpty()){
String sentence=makeSentence(second, dictionary, sentenceBuilder+foundWord+"
");
if(!sentence.isEmpty()){
return sentence;
}
}
}
}
return "";
}
53/56
Question: Write 2 functions to serialize and deserialize an
array of strings in Java
Write 2 functions to serialize and deserialize an array of strings. Strings can contain any
unicode character. Do not worry about string overflow.
Java implementation:
54/56
}
parsingDelimiter = true;
output[wordCount] = sb.toString();
wordCount++;
sb = new StringBuilder(); // Emptying.
}
}
return output;
}
Do not be one of the many who mistakenly believe that they have sufficient knowledge and
grip on algorithms.
The world of algorithms, will always to some extent remain mysterious. It takes a serious
effort to master them. If you are going for interview in a big company like, Google, Microsoft
, Amazon or Facebook.
Then you must be prepare very thoroughly about these. You do not need some surface
knowledge but very deep understanding of each aspects of algorithms.
55/56
In a world growing increasingly competent your survival in interview can only be ensured by
the mastery of algorithms.
References
https://www.amazon.com/Data-Structures-Algorithms-Java-2nd/dp/0672324539
http://introcs.cs.princeton.edu/java/40algorithms/
https://en.wikipedia.org/wiki/Search_algorithm
https://www.quora.com/
https://betterexplained.com/articles/sorting-algorithms/
http://www.javaworld.com/article/2073390/core-java/datastructures-and-algorithms-
part-1.html
https://www.quora.com/What-algorithm-questions-were-you-asked-at-an-Amazon-
Microsoft-Google-interview
https://www.quora.com/How-can-one-be-well-prepared-to-answer-data-structure-
algorithm-questions-in-interviews
56/56