You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tech-interview-handbook/contents/algorithms/study-cheatsheet.md

6.7 KiB

id title description keywords sidebar_label
study-cheatsheet Data structures and algorithms study cheatsheets for coding interviews Study guides for coding interviews with focus on data structures and algorithms, including practice questions, techniques, time complexity and recommended resources
coding interview algorithms
coding interview data structures
Introduction
<head> </head>

import InDocAd from '../_components/InDocAd';

What is this

This section dives deep into practical knowledge and techniques for algorithms and data structures which appear frequently in algorithm interviews. The more techniques you have in your arsenal, the higher the chances of passing the interview. They may lead you to discover corner cases you might have missed out or even lead you towards the optimal approach!

Contents of each study guide

For each topic, you can expect to find:

  1. A brief overview
  2. Learning resources
  3. Language-specific libraries to use
  4. Time complexities cheatsheet
  5. Things to look out for during interviews
  6. Corner cases
  7. Useful techniques vRecommended questions to practice

Study guides list

Here is the list of data structures and algorithms you should prepare for coding interviews and their corresponding study guides:

Topic Priority
Array High
String High
Hash Table Mid
Recursion Mid
Sorting and searching High
Matrix High
Linked List Mid
Queue Mid
Stack Mid
Tree High
Graph High
Heap Mid
Trie Mid
Interval Mid
Dynamic programming Low
Binary Low
Math Low
Geometry Low

General interview tips

Clarify any assumptions you made subconsciously. Many questions are under-specified on purpose.

Always validate input first. Check for invalid/empty/negative/different type input. Never assume you are given the valid parameters. Alternatively, clarify with the interviewer whether you can assume valid input (usually yes), which can save you time from writing code that does input validation.

Are there any time/space complexity requirements/constraints?

Check for off-by-one errors.

In languages where there are no automatic type coercion, check that concatenation of values are of the same type: int/str/list.

After finishing your code, use a few example inputs to test your solution.

Is the algorithm meant to be run multiple times, for example in a web server? If yes, the input is likely to be preprocess-able to improve the efficiency in each call.

Use a mix of functional and imperative programming paradigms:

  • Write pure functions as much as possible.
  • Pure functions are easier to reason about and can help to reduce bugs in your implementation.
  • Avoid mutating the parameters passed into your function especially if they are passed by reference unless you are sure of what you are doing.
  • However, functional programming is usually expensive in terms of space complexity because of non-mutation and the repeated allocation of new objects. On the other hand, imperative code is faster because you operate on existing objects. Hence you will need to achieve a balance between accuracy vs efficiency, by using the right amount of functional and imperative code where appropriate.
  • Avoid relying on and mutating global variables. Global variables introduce state.
  • If you have to rely on global variables, make sure that you do not mutate it by accident.

Generally, to improve the speed of a program, we can either: (1) choose a more appropriate data structure/algorithm; or (2) use more memory. The latter demonstrates a classic space vs. time tradeoff, but it is not necessarily the case that you can only achieve better speed at the expense of space. Also, note that there is often a theoretical limit to how fast your program can run (in terms of time complexity). For instance, a question that requires you to find the smallest/largest element in an unsorted array cannot run faster than O(N).

Data structures are your weapons. Choosing the right weapon for the right battle is the key to victory. Be very familiar about the strengths of each data structure and the time complexities for its various operations.

Data structures can be augmented to achieve efficient time complexities across different operations. For example, a hash map can be used together with a doubly-linked list to achieve O(1) time complexity for both the get and put operation in an LRU cache.

hash tables are probably the most commonly used data structure for algorithm questions. If you are stuck on a question, your last resort can be to enumerate through the common possible data structures (thankfully there aren't that many of them) and consider whether each of them can be applied to the problem. This has worked for me sometimes.

If you are cutting corners in your code, state that out loud to your interviewer and say what you would do in a non-interview setting (no time constraints). E.g., I would write a regex to parse this string rather than using split() which may not cover all cases.

import AlgorithmCourses from '../_courses/AlgorithmCourses.md'