Here you are going to see how to approach coding challenges like a pro and nail your next technical interview!
I wrote down everything that came to my mind while solving this challenge, until I arrived to a solution. In an interview setting, I would have done the same. This is how you want to practice for your coding challenges: as realistic as possible.
As you will see, there is no straightforward path to a solution. It’s unlikely that you’ll find the best approach from the beginning. Keep talking out loud, explaining your thought process as you explore different ideas.
I didn’t want to present just a solution to this problem. I wanted to recreate what went through my mind when I tried to solve it, to see also the approaches that didn’t arrive at anything meaningful, because this will happen in an interview. Just make sure you analyze them a bit before you start spending your precious time coding them.
Given an array nums
of n integers and an integer target, find three integers in nums
such that the sum is closest to target
. Return the sum of the three integers. You may assume that each input would have exactly one solution.
The first thing you need to do is to make sure you fully understand the problem you’re going to solve. Get used to rephrasing coding challenges using your own words. It is essential to create a few examples, including edge cases: repeated elements, empty array, etc.
Example 1:
Now we take note of the things that are relevant to this problem.
nums = [-1,-1,0,1]
is going to try the triplet (-1,0,1)
twice. At this point, this looks like a micro-optimization though.It is always a good first step to look for a brute force solution. If you’re in an interview, that will give you some points already and will make you feel confident.
For this problem, the brute force solution is very straightforward:
In C++, we would have the following code:
This code is correct. However, its time complexity is O(n^3)
, for a vector nums
of n
elements, because of the three nested loops. Let’s see how we can improve this.
Unfortunately, there isn’t a recipe to go from a brute-force to an optimal solution. Otherwise, it would be too easy! Sometimes this is more an art than a science, but here are some things worth trying:
Let’s see if we can use the previous list to find a better solution.
We already mentioned in Step 2 that we do not care about the order of the input. Let’s see what happens if we sort it.
nums = [-1, 2, -1, 1, 1, 2, 2, 2, -4, -4, -4, 1, -4], target = 1
sorted = [-4, -4, -4, -4, -1, -1, 1, 1, 1, 2, 2, 2, 2], target = 1
This problem is equivalent to this one, without all the duplicates:
sorted = [-4, -1, 1, 2], target = 1
With this, we have already reduced the size of our input, making the algorithm faster. We have added an extra O(n*log n)
step. However the overall complexity for the average case is still O(n^3)
. It looks like we have not gained much but we might end up using this idea later.
Let’s add this little trick to our previous code.
We might have marginally improved the performance for the case where there are many duplicates. For the average case, this code could be even slower due to the extra sorting step and all the new if
statements.
Let’s try another item from our list: simplification.
Let’s imagine we only need to find a pair whose sum is the closest to a given target. In this case, the brute force approach consist in computing the sum of all pairs, which will have a complexity of O(n^2)
.
We can also go through our previous list of things to try and see if it helps.
I have already solved a variant of this problem in my article How to Learn Data Structures And Algorithms. I will summarize here the gist of the technique and write the code to solve the problem. Basically, we create two pointers:
The variable sum
is initialized to nums[l] + nums[r]
. We know that if we increment l, because the array is sorted, the sum will be equal or greater than the current sum. Similarly, if we decrease r, the sum will be equal or smaller to the current sum.
The only difference is that in this problem we need to store the sum that is closest to the target. The code for this is the following:
This algorithm has a complexity of O(n * log n), because of the sorting step. If the input is already sorted, the complexity reduces to O(n). Either way, this is better that the brute-force approach.
We have an optimized solution for a simpler version of our problem. Can we take advantage of it? Certainly. Let’s see how in our previous example.
nums = [-1,2,1,-4], target = 1
In our iteration, for every value of i
, we can assume we take that element as the first element of the triple. Now, we just need to find the best solution in the rest of the array with a value of target - nums[i]
, because we already included nums[i]
in our solution.
You might have already recognized here the twoSum problem we just solved!
If we put all this pieces together, we arrive at the following code:
Since we are sorting the input, we may as well skip over repeated elements.
The overall complexity of this algorithm is O(n * log n) + O(n * n) ~ O(n^2)
, which is an improvement of a factor of n over the brute force solution!
After reading this article you have seen how I approached this problem, the different ideas that I tried, what I discarded (or saved for later) and how I ended up putting the different pieces together to arrive at the solution.
This is not for you to copy my approach step-by-step. I hope you will learn a thing or two and get inspired to be able to come up with resources the next time you are trying to solve a problem.
Note: to find the original problem statement, visit this link.
You have probably heard lately the terms tokens, crypto tokens, and cryptocurrencies. In this article,…
UTXO vs Account-Based Blockchains Introduction Bitcoin and Ethereum differ in many ways. In this article,…
This guide is a summary of my study notes for the Certified Kubernetes Application Developer…
Bloom filters are a data structure developed by Burton Howard Bloom in 1970. You can…
Merkle trees, also known as binary hash trees, are a type of binary tree. They…
In this article, I gave you an introduction to Dynamic Programming with several examples. Here…