Coding competitions are a common way to develop your programming skills or prepare yourself for job interviews. If you’re just getting started, it can be difficult to improve, especially as there isn’t really a good way to teach competitive coding aside from more practice. However, there are ways that you can learn more quickly and get up to speed with solving coding problems.
1. Finding a good practice website
The sentence “just practice more” might be one of the most useless pieces of advice out there, but finding a good source of practice material can be quite challenging when you’re starting with coding problems. DMOJ has a large amount of practice problems, but doesn’t really let you see others’ solutions which can sometimes be annoying. Coderbyte still has a good amount of problems and you can see other users’ solutions as well, which is nice if you need a hint. There are many more websites out there, so try to find one or more that you enjoy.
2. Studying loops, arrays and trees
Although it’s difficult to teach many concepts in competitive coding, such as problem solving and thinking of creative algorithms, there are definitely some recurring ideas despite each problem being unique. Loops, arrays and trees are an essential part of every competitive coder’s toolkit.
Let’s start with arrays. Arrays (or sometimes arraylists in Java) are pretty much the only way to keep track of large amounts of data. You almost always want to be taking the input in as an array, and manipulating said array to find answers.
Loops are the easiest way to go through your data and process it to find the answer to your coding problem. Be careful with nested loops; they can quickly increase the complexity of your problem and you’ll end up with a TLE (time limit exceeded). However, learning how to use loops effectively is essential for progression.
Trees are a bit more advanced than the previous two concepts, but are useful for searching through multiple possibilities quickly. Like with loops, they can make your program a lot slower if you code them improperly, but are an indispensable tool for analyzing. They’re quite complex so take your time to learn them properly.
3. Thinking about complexity (o-notation)
When thinking about a method to solve a problem, it’s a good idea to keep complexity in mind, which is often written using big O notation. Put simply, big O notation represents the time it takes to solve a problem as a function of how many inputs there are. It’s useful for figuring out what the worst-case scenario for your code is, and estimating how long it will take. Using big O notation, we can represent complexity in terms of O(n), with n being the number of inputs. Think about this as a regular function, with O as a constant: time=O(number of inputs).
For example, let’s say we have a simple loop that checks every number in the input. The complexity of this would be O(n): adding inputs increases our time linearly, since we’d have to do one extra check for one extra input. If we wrote another program that, for every number in an array, multiplied it with every other number in the array, the complexity would be O(n²). If we added one extra number, we would need to check the rest of the array an extra time. O complexity can be tough to understand, but it’s a useful concept for quickly checking if your solution seems right or not. If your O complexity is anything more than O(n²), you are probably doing something wrong.
4. Look at the limits of the problem inputs
Looking at the limits of the problem can help you keep track of fringe cases. If a problem says the input will be at most 100 lines, there is going to be a test case with 100 lines of input that you have to prepare for. Be on the lookout for the cases at the very limits of the input rules.
Looking at the limits of the problem inputs can also help you grab a few extra points in actual competitions. In many competitions, the input limits are often written as “For 4 of 15 points, there will be less than 100 lines of input. For another 6 of the 15 points, there are less than 1000 lines of input. For the final 5 points, there will be under 10000 lines of input.” If you’ve worked on the problem for a long time and can’t find a solution, or you’re running out of time in the competition, it’s a good idea to just aim for the lower-tier inputs. A lot of the time, you can write a much simpler algorithm that takes too long to work with the long inputs, but still gets you some points.
5. Global variables
Global variables are useful for keeping your data neat and tidy. Rather than adding a bunch of parameters in your functions or having to keep track of your returned data in a tree, you can just use a global array to keep track of everything. Just initialize the global variables at the top of your program and call them whenever you need information added to or taken out from a function you write.
6. Work smarter, not harder
After doing a few practice problems, you should be familiar with how difficult they are at your level. Don’t spend all your time writing complex, long programs if the other challenges in your difficulty category were all much quicker solves. Most coding problems can be solved by thinking out of the box and finding a clever way to manipulate the data rather than by writing a complex program that checks every condition of the problem.