Professional Documents
Culture Documents
Get started
Arslan Ahmad
Follow
Jul 18 · 8 min read
Coding interviews are getting harder every day. A few years back, brushing
up on key data structures and going through 50–75 practice questions was
more than enough prep for an interview. Today, everyone has access to
massive sets of coding problems, and they’ve gotten more di cult as well.
The overall interview process has gotten more competitive.
In this post, I’d like to share a strategy I follow to prepare for coding
interviews. My software engineering career spans around 15 years, in
which I’ve switched jobs ve times. I’ve given around 30 interview loops
containing 120+ interviews. I have some experience sitting on the other
side of the table too. I’ve taken 200+ coding interviews and 100+ system
design interviews.
https://medium.com/better-programming/the-ultimate-strategy-to-preparing-for-the-coding-interview-ee9f7eb439f3
How was I able to practice 12+ coding questions every day with a fulltime
job? Well, I wasn’t solving coding problems but practicing to map problems
onto problems that I’d already solved. I used to read a problem and spend a
few minutes to map it to a similar problem I’d seen before. If I could map it,
I’d focus only on the di erent constraints this problem had compared to the
parent problem. If it was a new problem, then I’d try to solve it and also
read around to nd smart ways other people used to devise its algorithm.
Over time, I developed a set of problem-patterns that helped me quickly
map a problem to an already-known one. Here are some examples of these
patterns:
1. If the given input is sorted (array, list, or matrix), then we will use a
variation of Binary Search or a Two Pointers strategy.
In the remaining post, I will share all the patterns I’ve collected and present
sample problems for a few. For a detailed discussion of these and related
problems with solutions take a look at Grokking the Coding Interview.
. . .
Example
Input: [1, 3, 8, 12, 4, 2], Output: 12
Solution
A bitonic array is a sorted array; the only di erence is that its rst part is
sorted in ascending order, and the second part is sorted in descending
order. We can use a variation of Binary Search to solve this problem.
Remember that in Binary Search we have start , end , and middle indices
and in each step we reduce our search space by moving start or end .
Since no two consecutive numbers are the same (as the array is
monotonically increasing or decreasing), whenever we calculate the middle
index for Binary Search, we can compare the numbers pointed out by the
index middle and middle+1 to nd if we are in the ascending or the
descending part. So:
part of the bitonic array. Therefore, our required number could either be
pointed out by middle or will be before middle . This means we will do end
= middle .
We can break when start == end . Due to the above two points, both
start and end will point at the maximum number of the Bitonic array.
Code
Here is the Java code to solve this problem:
See Code example 01 at the end of this post.
. . .
Write a function to return the indices of the two numbers (i.e., the pair)
such that they add up to the given target.
Example
Input: [1, 2, 3, 4, 6], target=6, Output: [1, 3] (The numbers at index 1
and 3 add up to 6: 2+4=6)
Solution
Since the given array is sorted, a brute-force solution could be to iterate
through the array, taking one number at a time and searching for the
second number through Binary Search. The time complexity of this
algorithm will be O(N*logN). Can we do better than this?
We can follow the Two Pointers approach. We will start with one pointer
pointing to the beginning of the array and another pointing at the end. At
every step, we will see if the numbers pointed by the two pointers add up to
the target sum. If they do, we’ve found our pair. Otherwise, we’ll do one of
two things:
1. If the sum of the two numbers pointed by the two pointers is greater
than the target sum, we need a pair with a smaller sum. So, to try more
pairs, we can decrement the end-pointer.
2. If the sum of the two numbers pointed by the two pointers is smaller
than the target sum, this means that we need a pair with a larger sum.
So, to try more pairs, we can increment the start-pointer.
Code
Here is what our algorithm will look like:
See Code example 02 at the end of this post.
. . .
Sample Problem
K closest points to the origin: Problem statement:
Given an array of points in a 2D plane, nd K closest points to the origin.
Example
Input: points = [[1,2],[1,3]], K = 1, Output: [[1,2]]
Solution
The Euclidean distance of a point P(x,y) from the origin can be calculated
through the following formula:
We can use a Max Heap to nd K points closest to the origin. We can start
with pushing K points in the heap. While iterating through the remaining
points, if a point (say P) is closer to the origin than the top point of the
max-heap, we will remove that top point from the heap and add P to
always keep the closest points in the heap.
Code
Here is what our algorithm will look like:
See Code example 03 at the end of this post.
. . .
Sample Problem
Subsets: Problem statement
Given a set with distinct elements, nd all of its distinct subsets.
Example
Input: [1, 5, 3], Output: [], [1], [5], [3], [1,5], [1,3], [5,3], [1,5,3]
Solution
To generate all subsets of the given set, we can use the Breadth-First Search
(BFS) approach. We can start with an empty set, iterate through all
numbers one-by-one, and add them to existing sets to create new subsets.
2. Add the rst number (1) to all the existing subsets to create new subsets:
[[], [1]];
3. Add the second number (5) to all the existing subsets: [[], [1], [5],
[1,5]];
4. Add the third number (3) to all the existing subsets: [[], [1], [5], [1,5],
[3], [1,3], [5,3], [1,5,3]].
Code
Here is what our algorithm will look like:
See Code example 04 at the end of this post.
. . .
Sample Problem
Binary Tree Path Sum: Problem Statement
Given a binary tree and a number S, nd if the tree has a path from root-to-
leaf such that the sum of all the node values of that path equals S.
Solution
As we are trying to search for a root-to-leaf path, we can use the Depth First
Search (DFS) technique to solve this problem.
To recursively traverse a binary tree in a DFS fashion, we can start from the
root and, at every step, make two recursive calls, one for the left and one for
the right child.
Here are the steps for our Binary Tree Path Sum problem:
2. If the current node is not a leaf node, do two things: a) Subtract the
value of the current node from the given number to get a new sum =>
S = S - node.value, b) Make two recursive calls for both the children
of the current node with the new number calculated in the previous
step.
3. At every step, see if the current node being visited is a leaf node and if its
value is equal to the given number S. If both are true, we have found the
required root-to-leaf path, therefore return true .
4. If the current node is a leaf, but its value is not equal to the given
number S, return false.
Code
Here is what our algorithm will look like:
See Code example 05 at the end of this post.
Following these patterns helped me tremendously to save time for my
coding interview prep. Take a look at Grokking the Coding Interview and
Grokking Dynamic Programming Patterns for Coding Interviews to nd
more of such patterns and their sample problems.
1.6K claps
WRITTEN BY
Arslan Ahmad
Follow
Better Programming
Follow
10.4K
10.4K
1.8K
Discover Medium
Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Make Medium yours
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Become a member
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade
AboutHelpLegal
Code example 01
Code example 02
Code example 03
Code example 04
Code example 05