A Beginner’s Guide to Algorithms

Jeffrey Ogah
The Startup
Published in
9 min readAug 1, 2019

An algorithm is basically a set of steps taken to solve a problem. This process isn’t always easy, even for experienced developers. Newer developers also sometimes get stuck, not knowing how to approach a problem or where to get started. Here I’ll talk about some things you could do to simplify this process and hopefully boost your problem solving skills! We’ll also go through a challenge while implementing the steps here.

Read. Then read again

It may seem simplistic, but this is an important first step. It’s difficult to solve a problem you don’t understand, and to understand the problem, you’ll need to read it a couple times. There’s no set amount on how many times you should do this, or how fast/slow you should. Whatever works for you is fine. Try to break the problem into bits as you re-read, creating a mental picture as you go along.

Here is a sample problem we’ll solve together. We’ll use JavaScript to solve this, but you can use pretty much any language to reproduce it. The major difference will be in syntax and perhaps implementation.

Rearrange Array Elements so as to form two numbers such that their sum is maximum possible. The number of digits in both the numbers cannot differ by more than 1. Attempt to solve this without using a built-in sorting function.for e.g. [1, 2, 3, 4, 5]The expected answer would be [531, 42]. Another expected answer can be [542, 31]. In scenarios such as these when there are more than one possible answers, return any one.

In the above problem, we’re tasked with creating two numbers such that when added together, we’d have the maximum sum possible. If you don’t immediately understand the challenge, that’s fine. Take some time to re-read again, evaluating the requirements, sample output and what is expected.

Break ’em down

Next will be to break it into bits and pieces. You can ask some simple questions here to better understand the problem. Sample questions are:

  • Am I working with any input? If yes, what data type is involved?
  • What sort of computation am I doing? Is it mathematical? Logical? Both? etc.
  • What am I required to do?
  • What sort of output is expected?

These are some general questions, but depending on the problem, you might have different set of questions. It’s also fine if your breakdown is vague, the idea is to get started. In the above challenges, after breaking it down, we could have this:

  • Accept an array of numbers as input
  • Create two numbers containing a combination of the numbers from the array
  • Confirm the number of digits in both arrays are either the same (if the array had an even number of elements) or differ by one (if the array had an odd number of elements)
  • Ensure the sum of both numbers is the largest possible number
  • Return an array containing these two numbers

With this, we have a pretty good picture of what exactly we need to do.

Solve the problem manually

You’ve probably heard that computers are dumb. It’s garbage in, garbage out. Arguments may be made that with machine learning and artificial intelligence the above isn’t entirely accurate but that’s beside the point. Essentially, the computer isn’t going to solve the problem for you, that’s the reason we write codes, to give instructions detailing what we want the computer to do. If you want to write a piece of code to solve a problem, you need to be able to solve the problem yourself, or at least understand the steps enough.

This part is usually where logic and problem solving ability comes in. It’s also arguably the hardest part, but the good news is that with practice, you can improve your problem solving ability. Earlier we broke our problem statement into bits. There is one major part that requires logic, the other parts are mostly flavor that are more based on syntax. Accepting input or providing an output can be done relatively easily. Creating numbers and ensuring the number of digits are the same the same or differ by one can also be worked out a bit easily. However, the fourth point is a bit vague and requires more thought

Ensure the sum of both numbers is the largest possible number

It’s vague and open-ended. We don’t know the numbers we are working with beforehand, or how many numbers are involved. Testing sums of all possible combinations (brute-force) is potentially one way although we would be left with a rather inefficient solution. It’s not too difficult to imagine why, with more input, our program will exponentially increase in complexity and end up using too many resources.

We’ve decided brute-force isn’t exactly an ideal approach so let’s look at something else. Since we’re looking for the highest sum, it makes sense that the biggest numbers will combine to form the highest numbers. After all, 5+6 will give a higher number than 4+5. Let’s test our approach with the sample input. Essentially, we’ll lump the biggest numbers together and see what we get.

input- [1, 2, 3, 4, 5]
numbers- [543,21]
sum- 564

But wait, something isn’t quite right. Based on the expected output, we should have had something like this

input- [1, 2, 3, 4, 5]
numbers- [531, 42]
sum- 573

Our presumed solution is a bit off. One good thing about testing manually this way is that you can immediately see what works and what doesn’t without having to immediately worry about implementation. If you observe our previous approach a bit more, you may notice why it didn’t work. Take some minutes to analyse it first.

Were you able to figure it out? Well, we were on track with adding biggest numbers because we know that certainly bigger numbers added together give bigger sum totals. However, we didn’t actually do this in the first approach. We grouped all the biggest numbers together in the first generated number, thus leaving smaller numbers in the corresponding number positions of the second generated number. Writing it out will make this a bit clearer

First approach
first 543 (the biggest numbers are already grouped here)
second + 21 (smaller numbers here)
total = 564
Expected approach
first 531 (Every other big number is grouped here)
second + 42 (same thing here)
total = 573

Our first approach is actually mapping smaller numbers in the same positions, so we’re not adding the biggest numbers at all. Like this it’s a bit easier to understand what we should do. If we alternate between passing the highest numbers between the first and second generate number, then the biggest numbers get paired. Let’s assume we call our variables firstNum and secondNum, then our process will be something like this:

  • Add highest number to firstNum
  • Add second highest number to secondNum
  • Add third highest number to firstNum
  • repeat ….

By add here, I mean concatenate (or join) and by doing this, we will pair the biggest numbers together each time and thus produce the biggest sum.

Use Pseudo-code

Now it’s time to write a mock or something a bit closer to code than the algorithm we derived earlier. Our pseudo-code can look like this

function largestSum(arr){
/* create a temporary array to prevent mutation of original array
create two empty strings- firstNum and secondNum to hold the created numbersinitialize loopfind the largest number in the arrayalternatively concatenate largest number between firstNum and secondNumremove largest number from array so the next largest number can be foundrepeat steps until no numbers remain in the arrayreturn array consisting of firstNum and secondNum */}

Our function accepts an array of numbers (arr). First I create a temporary array with the same values. This is to avoid mutation. A good rule is to work without mutating (or changing) the values of the original array or object that was passed as an input. Next I create two variables (firstNum and secondNum) to hold the numbers we create. Afterwards, we start a loop with the following steps:

  • Find the largest number in the temporary array
  • Add (concatenate) this number with firstNum or secondNum alternatively
  • Remove the largest number from the temporary array
  • Return to step 1 and repeat until there are no numbers left

Writing your pseudo-code with comments like this is also helpful because the comments are explanatory so you know what you’re trying to do at each point. You could even leave the comments for readability and understanding (we’ll talk a bit about this later)

Write code, then test

At this point, you’ve done a lot of the heavy lifting already. About half of the work is done now, what’s left is basically syntax. It’s fine if you don’t have the necessary code in your head, and that’s not the important part. You’ll naturally get better with time and muscle memory as you work. You can check official documentation of the language you’re using, use Google or StackOverflow to assist you.

Here’s a sample code to solve the problem based on our pseudo-code

function largestSum(arr){
let tempArr = [...arr]
let firstNum = "", secondNum = "", maxNum, maxIndex;

for (let num in arr) {
maxNum = Math.max(...tempArr); //find max number
maxIndex = tempArr.indexOf(maxNum)
if (num % 2 === 0) { //alternate concatenation
firstNum += maxNum;
}
else {
secondNum += maxNum;
}
tempArr.splice(maxIndex,1) //delete used max Number
}

return [firstNum, secondNum]
}

This is a JavaScript implementation as mentioned earlier. If you go through the pseudo-code and the code, you will be able to understand how it works. I’ve included some comments as well. It’s encouraged to include comments in your code. Someone else may not immediately understand what you’re doing or why you did it. In addition, if you return to the same code you wrote some months back, you’d essentially have become a stranger and might struggle to recall why you did something. Comments generally simplify the steps so always try to include them.

Lastly, you should test your code, check for possible bugs and try to break it. It’s much better if you find a loophole and fix it compared to someone else doing that. Find what works, what doesn’t work and why, then try to resolve the troublesome cases. For example, your solution may work for an array of even number size but not odd. Observe to figure out what’s causing the break and work to fix it.

Optimize and simplify

Usually, the first step is to get the code working regardless of how inefficient it may be. Once you have a working solution, you should then look for ways to optimize it. You could ask some questions like these:

  • Are you using too many variables?
  • Are the variables names descriptive enough?
  • Was that loop or conditional really necessary?
  • How about defining another function if you are repeating steps?
  • What about using higher-order or built-in functionality?

There are usually many ways to optimize code by reducing the complexity. It’s a bonus if you can improve readability as well. This is also something you improve with time as you grow.

Study other solutions and get feedback

So now you finally managed to solve the problem, but there are usually numerous ways to tackle the same problem. Try to find other solutions to the same problem. Carefully observe their methodology and try to understand the approach used. A lot of times, you learn better ways to approach problems as well as potential ways to optimize your own solution. I make it a rule to always check at least 3 other solutions to every problem I solve (where possible) to learn more. I can’t count how many times I’ve ended being surprised by an ingenious approach. You’ll get to see a lot of “out-of-the-box” approaches solving the same problem in brilliant ways.

If possible, also try to get feedback on your code. You could host your solution somewhere eg GitHub or just show others. If you’re in a developer community, a WhatsApp group, or maybe even a Slack workspace, you can share you solution and ask for feedback. Some communities are centered around solving problems like these. You’ll gain immense value by doing these.

Practice

Finally, if you really want to improve, you’d have to practice over and over again. Try to solve problems as often as possible, employing the above steps (especially review and studying other solutions). This is guaranteed to improve your problem solving skills.

There are some amazing platforms that have thousands of challenge problems of varying levels. Look for something close to your level of competency and solve it, but don’t spend too long solving easy challenges otherwise you won’t get to flex and improve your skills. Codewars and HackerRank are good sites to test your skills.

Hope these will be able to help you in some way.

--

--