Squash commit

This commit is contained in:
Tay Yang Shun
2017-09-20 15:27:28 +08:00
commit 2182a70770
70 changed files with 5486 additions and 0 deletions

522
algorithms/README.md Normal file
View File

@@ -0,0 +1,522 @@
Algorithm Questions
==
Here are some tips and questions you can think in your head or clarify with the interviewer. They may lead you to
discover corner cases you might have missed out or even lead you towards the optimal approach!
## Contents
- [Array](array.md)
- [Dynamic Programming and Memoization](dynamic-programming.md)
- [Geometry](geometry.md)
- [Graph](graph.md)
- [Hash Table](hash-table.md)
- [Heap](heap.md)
- [Interval](interval.md)
- [Linked List](linked-list.md)
- [Math](math.md)
- [Matrix](matrix.md)
- [Object-Oriented Programming](oop.md)
- [Permutation](permutation.md)
- [Queue](queue.md)
- [Sorting and Searching](sorting-searching.md)
- [Stack](stack.md)
- [String](string.md)
- [Tree](tree.md)
## Picking a Programming Language
Before anything else, you need to pick a programming language to do your interviews in. Most companies will let you code in any language you want, the only exception I know being Google, where they only allow candidates to pick from Java, C++ or Python for their algorithmic coding interviews. Most of the time, I would recommend that you use a language that you are extremely familiar with rather than picking up a new language just for doing interviews because the company uses that language heavily.
There are some languages which are more suitable than others for coding interviews and some languages you absolutely want to avoid. From my experience interviewing as an interviewer, most candidates pick Python or Java. Other commonly seen languages include JavaScript, Ruby and C++. I would absolutely avoid lower level languages like C or Go, simply because they lack in many standard library functions and data structures.
Personally, Python is my de facto choice for coding algorithms during interviews because it is succinct and has a pretty huge library of functions and data structures available. One of my top reasons for recommending Python is that it uses consistent APIs that operate on different data structures, such as `len()`, `for ... in ...` and slicing notation on sequences (strings/lists/tuples). Getting the last element in a sequence is `arr[-1]` and reversing it is simply `arr[::-1]`. You can achieve a lot with minimal syntax in Python.
Java is a decent choice too but having to constantly declare types in your code means extra keystrokes which results in slower coding/typing speed. This issue will be more apparent when you have to write on a whiteboard during on-site interviews. The reasons for choosing/not choosing C++ are similar to Java. Ultimately, Python, Java and C++ are decent choices of languages. If you have been using Java at work for a while now and do not have time to be comfortably familiar with another language, I would recommend just sticking to Java instead of picking up Python from scratch just for interviews to avoid having to context switch between languages during work vs interviews. Most of the time, the bottleneck is in the thinking and not the writing.
One exception to the convention of allowing you to "pick any programming language you want" is when you are interviewing for a domain-specific position, such as Front End/iOS/Android Engineer roles, in which you would need to be familiar with coding algorithms in JavaScript, Objective-C/Swift and Java respectively. If you need to use a data structure that the language does not support, such as a Queue or Heap in JavaScript, perhaps try asking the interviewer whether you can assume that you have a data structure that implements certain methods with specified time complexities. If the implementation of that data structure is not crucial to solving the problem, the interviewer will usually allow it. In reality, being aware of existing data structures and selecting the appropriate ones to tackle the problem at hand is more important than knowing the intricate implementation details.
## Revise your CS101
If you have been out of college for a while, it will be highly advisable to revise the CS fundamentalsAlgorithms and Data Structures. Personally I prefer to revise as I practiced so I scanned through my college notes and revised the various algorithms as I worked on the algorithm problems from LeetCode and Cracking the Coding Interview.
This [interviews repository](https://github.com/kdn251) by Kevin Naughton Jr. served as a quick refresher for me.
## Mastery through Practice
Next, gain familiarity and mastery of the algorithms and data structures in your chosen programming language:
1. Practice coding algorithms using your chosen language. While [Cracking the Coding Interview](http://www.crackingthecodinginterview.com/) is a good resource for practice, I prefer being able to type code, run it and get instant feedback. There are various Online Judges such as [LeetCode](https://leetcode.com/), [HackerRank](https://www.hackerrank.com/) and [CodeForces](http://codeforces.com/) for you to practice questions online and get used to the language. From experience, LeetCode questions are the most similar to the kind of questions being asked in interviews whereas HackerRank and CodeForces questions are more similar to competitive programming questions. If you practice enough LeetCode questions, there is a good chance that you would have seen/done your actual interview question (or some variant) on LeetCode before.
2. Learn and understand the time and space complexities of the common operations in your chosen language. For Python, this [page](https://wiki.python.org/moin/TimeComplexity) will come in handy. Also find out the underlying sorting algorithm that is being used in the language's `sort()` function and its time and space complexity (in Python its Timsort which is a hybrid sort). After completing a question on LeetCode, I usually add the time and space complexities of the written code as comments above the function body to remind myself to analyze the algorithm after I am done with the implementation.
3. Read up on the recommended coding style for your language and stick to it. If you have chosen Python, refer to the PEP 8 Style Guide. If you have chosen Java, refer to Googles Java Style Guide.
4. Find out and be familiar with the common pitfalls and caveats of the language. If you point out them out during the interview and intelligently avoid falling into them, you will usually impress the interviewer and that results in bonus points in your feedback, regardless of whether the interviewer is familiar with the language or not.
5. Gain a broad exposure to questions from various topics. In the second half of the article I mention algorithm topics and practice questions for each topic. Do around 100200 LeetCode questions and you should be good.
Practice, practice and more practice!
## Phases of a Coding Interview
Congratulations, you are ready to put your skills into practice! In a real coding interview, you will be given a technical question by the interviewer, write code in a real-time collaborative editor (phone screen) or on a whiteboard (on-site) to solve the problem within 3045 minutes. This is where the real fun begins!
Your interviewer will be looking out for signals that you fit the requirements of the role and it is up to you to display those signals to them. Initially it may feel weird to be talking while you are coding as most programmers do not have the habit of explaining out loud as they are typing code. However, it is hard for the interviewer to know what you are thinking just by looking at the code that you type. If you communicate your approach to the interviewer before you start coding, you can validate your approach with him and the both of you can agree upon an acceptable approach.
**Before the Interview (Remote)**
For phone screens/remote interviews, prepare paper and pen/pencil to jot down and visualize stuff. If you are given a question on trees and graphs, it usually helps if you draw out some examples of the data structure given in the question.
Use earphones and make sure you are in a quiet environment. You definitely do not want to be holding a phone in one hand and only be able to type with the other. Try avoiding using speakers because if the echo is bad, communication is harder and repeating of words will just result in loss of valuable time.
**Upon Getting the Question**
Many candidates jump into coding the moment they hear the question. That is usually a big mistake. Take a moment to repeat the question back at the interviewer and make sure that you understand exactly what he is asking. If you misunderstood and when you repeat back the question, he'll clarify.
Always seek clarification about the question upon hearing it even if it you think it is clear to you. You might discover something that you have missed out and it also sends a signal to the interviewer that you are a careful person who pays attention to details. Consider asking the following questions:
- How big is the size of the input?
- How big is the range of values?
- What kind of values are there? Are there negative numbers? Floating points? Will there be empty inputs?
- Are there duplicates within the input?
- What are some extreme cases of the input?
- How is the input stored? If you are given a dictionary of words, is it a list of strings or a Trie?
After you have sufficiently clarified the scope and intention of the problem, explain your high level approach to the interviewer even if it is a naive solution. If you are stuck, consider various approaches and explain out loud why it will/will not work. Sometimes your interviewer might drop hints and lead you towards the right path.
Start with a brute force approach, communicate it to the interviewer, explain the time and space complexity and why it is bad. It is unlikely that the brute force approach will be one that you will be coding. At this point, the interviewer will usually pop the dreaded "Can we do better?" question, meaning that he is looking for a more optimal approach. In my opinion, this is usually the hardest part of the interview. In general, look for repeated work and try to optimize them by potentially caching the calculated result somewhere and reference it later, rather than having to compute it all over again. There are some tips on tackling topic-specific questions that I dive into details below.
Only start coding after you and your interviewer have agreed on an approach and has given you the green light.
**Starting to Code**
Write your code with good coding style. Reading code written by others is usually not an enjoyable task. Reading horribly-formatted code by others makes it worse. Your goal is to make your interviewer understand the code you have written so that he can quickly evaluate if your code does what you say it does and whether it solves the given problem. Use clear variable names, avoid single letter names unless they are for iteration. However, if you are coding on a whiteboard, you might not want to use extremely verbose variable names for the sake of reducing the amount you have to write.
Always be explaining what you are currently writing/typing to the interviewer. This is not about literally reading out what you are typing to the interviewer. Talk about the section of the code you are currently implementing at a higher level, explain why it is written as such and what it is trying to achieve.
When you copy and paste code, consider whether it is necessary. Sometimes it is, sometimes it is not. If you find yourself copying and pasting one large chunk of code spanning multiple lines, it is probably an indicator that you can refactor by containing those lines into a function. If it is just a single line you copied, usually it is fine. Do remember to change the respective variables in your copied line of code where relevant. Copy-paste errors are a common source of bugs even in day-to-day coding!
**After Coding**
After you have finished coding, do not immediately announce to the interviewer that you are done. In most cases, your code is usually not perfect and contains some bugs or syntax errors. What you need to do now is to review your code.
Firstly, look through your code from start to finish as if it is the first time you are seeing it, as if it was written by someone else and you are trying to spot bugs in it. Thats exactly what your interviewer will be doing. Look through and fix any minor issues you may find.
Next, come up with small test cases and step through the code (not your algorithm!) with those sample input. Interviewers like it when you read their mind and what they usually do after you have finished coding would be to get you to write tests. It is a huge plus if you write tests for your code even before prompts from them. You should be emulating a debugger when stepping through and jot down or say out the values of certain variables as you step through the lines of code.
If there are huge duplicated chunks of code in your solution, it would be a good chance to refactor it and demonstrate to the interviewer that you are one who values code quality. Also look out for places where you can do [short-circuit evaluation](https://en.wikipedia.org/wiki/Short-circuit_evaluation).
Lastly, give the time/space complexity of your code and explain why it is such. You can even annotate certain chunks of your code with the various time/space complexities to demonstrate your understanding of your code and the APIs of your chosen programming language. Explain any trade-offs in your current approach vs alternative approaches, possibly in terms of time/space.
If your interviewer is happy with the solution, the interview usually ends here. It is also not uncommon that the interviewer asks you extension questions, such as how you would handle the problem if the whole input is too large to fit into memory, or if the input arrives as a stream. This is a common follow-up question at Google where they care a lot about scale. The answer is usually a divide-and-conquer approachperform distributed processing of the data and only read certain chunks of the input from disk into memory, write the output back to disk and combine them later on.
## Practicing via Mock Interviews
Interviewing is a skill that you can get better at. The steps mentioned above can be rehearsed over and over again until you have fully internalized them and following those steps become second nature to you. A good way to practice is to find a friend to partner with and the both of you can take turns to interview each other.
A great resource for practicing mock coding interviews would be [interviewing.io](https://interviewing.io/). interviewing.io provides free, anonymous practice technical interviews with Google and Facebook engineers, which can lead to real jobs and internships. By virtue of being anonymous during the interview, the inclusive interview process is de-biased and low risk. At the end of the interview, both interviewer and interviewees can provide feedback to each other for the purpose of improvement. Doing well in your mock interviews will unlock the jobs page and allow candidates to book interviews (also anonymously) with top companies like Uber, Lyft, Quora, Asana and more. For those who are totally new to technical interviews, you can even view a [demo interview](https://start.interviewing.io/interview/9hV9r4HEONf9/replay) on the site (requires sign in).
I have used interviewing.io both as an interviewer and an interviewee and found the experience to be really great! [Aline Lerner](https://twitter.com/alinelernerLLC), the CEO and co-founder of interviewing.io and her team are passionate about revolutionizing the technical interview process and helping candidates to improve their skills at interviewing. She has also published a number of technical interview-related articles on the [interviewing.io blog](http://blog.interviewing.io/). interviewing.io is still in beta now but I recommend signing up as early as possible to increase the likelihood of getting an invite.
Another platform that allows you to practice coding interviews is [Pramp](https://pramp.com/). Where interviewing.io matches potential job seekers with seasoned technical interviewers, Pramp differs takes a different approach. Pramp pairs you up with another peer who is also a job seeker and both of you take turns to assume the role of interviewer and interviewee. Pramp also prepares questions for you, along with suggested solutions and prompts to guide the interviewee. Personally, I do not really like Pramp's approach because if I were to interview someone, I would rather choose a question I am familiar with. Also, many users of the platform do not have the experience of being interviewers and that can result in a horrible interview experience. There was once where my matched peer, as the interviewer, did not have the right understanding of the question and attempted to lead me down the wrong path of solving the question.
The next section dives deep into practical tips for specific topics of algorithms and data structures which appear frequently in coding questions. Many algorithm questions involve techniques that can be applied to questions of similar nature. The more techniques you have in your arsenal, the higher the chances of passing the interview. For each topic, there is also a list of recommended common questions which in my opinion is highly valuable for mastering the core concepts for the topic.
## General Tips
- Input validation:
- 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 corner cases:
- 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 choose a more appropriate data structure/algorithm or use more memory. It's a classic space/time tradeoff.
- 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](https://leetcode.com/problems/lru-cache/).
- Hashmaps 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 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 does not cover all cases.
## Sequence
- Arrays and strings are considered sequences (a string is a sequence of characters). There are tips relevant for dealing with both arrays and strings which will be covered here.
- Are there duplicate values in the sequence, would it affect the answer?
- Check for sequence out of bounds.
- Be mindful about slicing or concatenating sequences in your code. Typically, slicing and concatenating sequences require O(n) time. Use start and end indices to demarcate a subarray/substring where possible.
- Sometimes you can traverse the sequence from the right rather than from the left.
- Master the [sliding window technique](https://discuss.leetcode.com/topic/30941/here-is-a-10-line-template-that-can-solve-most-substring-problems) that applies to many substring/subarray problems.
- When you are given two sequences to process, it is common to have one index per sequence to traverse/compare the both of them. For example, we use the same approach to merge two sorted arrays.
- Corner cases:
- Empty sequence.
- Sequence with 1 or 2 elements.
- Sequence with repeated elements.
## Array
- Is the array sorted or partially sorted? If it is, some form of binary search should be possible. This also usually means that the interviewer is looking for a solution that is faster than O(n).
- Can you sort the array? Sometimes sorting the array first may significantly simplify the problem. Make sure that the order of array elements do not need to be preserved before attempting a sort.
- For questions where summation or multiplication of a subarray is involved, pre-computation using hashing or a prefix/suffix sum/product might be useful.
- If you are given a sequence and the interviewer asks for O(1) space, it might be possible to use the array itself as a hash table. For example, if the array only has values from 1 to N, where N is the length of the array, negate the value at that index (minus one) to indicate presence of that number.
#### Practice Questions
- [Two Sum](https://leetcode.com/problems/two-sum/)
- [Best Time to Buy and Sell Stock](https://leetcode.com/problems/best-time-to-buy-and-sell-stock/)
- [Contains Duplicate](https://leetcode.com/problems/contains-duplicate/)
- [Product of Array Except Self](https://leetcode.com/problems/product-of-array-except-self/)
- [Maximum Subarray](https://leetcode.com/problems/maximum-subarray/)
- [Maximum Product Subarray](https://leetcode.com/problems/maximum-product-subarray/)
- [Find Minimum in Rotated Sorted Array](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/)
- [Search in Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/)
- [3Sum](https://leetcode.com/problems/3sum/)
- [Container With Most Water](https://leetcode.com/problems/container-with-most-water/)
## Binary
- Questions involving binary representations and bitwise operations are asked sometimes and you must be absolutely familiar with how to convert a number from decimal form into binary form (and vice versa) in your programming language of choice.
- Test k<sup>th</sup> bit is set: `num & (1 << k) != 0`.
- Set k<sup>th</sup> bit: `num |= (1 << k)`.
- Turn off k<sup>th</sup> bit: `num &= ~(1 << k)`.
- Toggle the k<sup>th</sup> bit: `num ^= (1 << k)`.
- To check if a number is a power of 2, `num & num - 1 == 0`.
#### Practice Questions
- [Sum of Two Integers](https://leetcode.com/problems/sum-of-two-integers/)
- [Number of 1 Bits](https://leetcode.com/problems/number-of-1-bits/)
- [Counting Bits](https://leetcode.com/problems/counting-bits/)
- [Missing Number](https://leetcode.com/problems/missing-number/)
- [Reverse Bits](https://leetcode.com/problems/reverse-bits/)
## Dynamic Programming
- Usually used to solve optimization problems.
- Alaina Kafkes has written an [awesome post](https://medium.freecodecamp.org/demystifying-dynamic-programming-3efafb8d4296) on tackling DP problems.
- The only way to get better at DP is to practice. It takes some amount of practice to be able to recognize that a problem can be solved by DP.
- Sometimes you do not need to store the whole DP table in memory, the last two values or the last two rows of the matrix will suffice.
#### Practice Questions
- 0/1 Knapsack
- [Climbing Stairs](https://leetcode.com/problems/climbing-stairs/)
- [Coin Change](https://leetcode.com/problems/coin-change/)
- [Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/)
- [Longest Common Subsequence]()
- [Word Break Problem](https://leetcode.com/problems/word-break/)
- [Combination Sum](https://leetcode.com/problems/combination-sum-iv/)
- [House Robber](https://leetcode.com/problems/house-robber/) and [House Robber II](https://leetcode.com/problems/house-robber-ii/)
- [Decode Ways](https://leetcode.com/problems/decode-ways/)
- [Unique Paths](https://leetcode.com/problems/unique-paths/)
- [Jump Game](https://leetcode.com/problems/jump-game/)
## Geometry
- When comparing euclidean distance between two pairs of points, using dx<sup>2</sup> + dy<sup>2</sup> is sufficient. It is unnecessary to square root the value.
- To find out if two circles overlap, check that the distance between the two centers of the circles is less than the sum of their radii.
## Graph
- Be familiar with the various graph representations, graph search algorithms and their time and space complexities.
- You can be given a list of edges and tasked to build your own graph from the edges to perform a traversal on. The common graph representations are:
- Adjacency matrix.
- Adjacency list.
- Hashmap of hashmaps.
- Some questions look like they are trees but they are actually graphs. In that case you will have to handle cycles and keep a set of visited nodes when traversing.
- Graph search algorithms:
- **Common** - Breadth-first Search, Depth-first Search
- **Uncommon** - Topological Sort, Dijkstra's algorithm
- **Rare** - Bellman-Ford algorithm, Floyd-Warshall algorithm, Prim's algorithm, Kruskal's algorithm
- In coding interviews, graphs are commonly represented as 2-D matrices where cells are the nodes and each cell can traverse to its adjacent cells (up/down/left/right). Hence it is important that you be familiar with traversing a 2-D matrix. When recursively traversing the matrix, always ensure that your next position is within the boundary of the matrix. More tips for doing depth-first searches on a matrix can be found [here](https://discuss.leetcode.com/topic/66065/python-dfs-bests-85-tips-for-all-dfs-in-matrix-question/). A simple template for doing depth-first searches on a matrix goes like this:
```py
def traverse(matrix):
rows, cols = len(matrix), len(matrix[0])
visited = set()
directions = ((0, 1), (0, -1), (1, 0), (-1, 0))
def dfs(i, j):
if (i, j) in visited:
return
visited.add((i, j))
# Traverse neighbors
for direction in directions:
next_i, next_j = i + direction[0], j + direction[1]
if 0 <= next_i < rows and 0 <= next_j < cols: # Check boundary
# Add any other checking here ^
dfs(next_i, next_j)
for i in range(rows):
for j in range(cols):
dfs(i, j)
```
- Corner cases:
- Empty graph.
- Graph with one or two nodes.
- Disjoint graphs.
- Graph with cycles.
#### Practice Questions
- [Clone Graph](https://leetcode.com/problems/clone-graph/)
- [Course Schedule](https://leetcode.com/problems/course-schedule/)
- [Alien Dictionary](https://leetcode.com/problems/alien-dictionary/)
- [Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/)
- [Number of Islands](https://leetcode.com/problems/number-of-islands/)
- [Graph Valid Tree](https://leetcode.com/problems/graph-valid-tree/)
- [Number of Connected Components in an Undirected Graph](https://leetcode.com/problems/number-of-connected-components-in-an-undirected-graph/)
- [Longest Consecutive Sequence](https://leetcode.com/problems/longest-consecutive-sequence/)
## Interval
- Interval questions are questions where you are given an array of two-element arrays (an interval) and the two values represent a start and an end value. Interval questions are considered part of the array family but they involve some common techniques hence they are extracted out to this special section of their own.
- An example interval array: `[[1, 2], [4, 7]]`.
- Interval questions can be tricky to those who have not tried them before because of the sheer number of cases to consider when they overlap.
- Do clarify with the interviewer whether `[1, 2]` and `[2, 3]` are considered overlapping intervals as it affects how you will write your equality checks.
- A common routine for interval questions is to sort the array of intervals by each interval's starting value.
- Be familiar with writing code to check if two intervals overlap and merging two overlapping intervals:
```py
def is_overlap(a, b):
return a[0] < b[1] and b[0] < a[1]
def merge_overlapping_intervals(a, b):
return [min(a[0], b[0]), max(a[1], b[1])]
```
- Corner cases:
- Single interval.
- Non-overlapping intervals.
- An interval totally consumed within another interval.
- Duplicate intervals.
#### Practice Questions
- [Insert Interval](https://leetcode.com/problems/insert-interval/)
- [Merge Intervals](https://leetcode.com/problems/merge-intervals/)
- [Meeting Rooms](https://leetcode.com/problems/meeting-rooms/) and [Meeting Rooms II](https://leetcode.com/problems/meeting-rooms-ii/)
- [Non-overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/)
## Linked List
- Like arrays, linked lists are used to represent sequential data. The benefit of linked lists is that insertion and deletion from anywhere in the list is O(1) whereas in arrays the following elements will have to be shifted.
- Adding a dummy node at the head and/or tail might help to handle many edge cases where operations have to be performed at the head or the tail. The presence of dummy nodes essentially ensures that operations will never have be done on the head or the tail, thereby removing a lot of headache in writing conditional checks to dealing with null pointers. Be sure to remember to remove them at the end of the operation.
- Sometimes linked lists problem can be solved without additional storage. Try to borrow ideas from reverse a linked list problem.
- For deletion in linked lists, you can either modify the node values or change the node pointers. You might need to keep a reference to the previous element.
- For partitioning linked lists, create two separate linked lists and join them back together.
- Linked lists problems share similarity with array problems, think about how you would do it for an array and try to apply it to a linked list.
- Two pointer approaches are also common for linked lists. For example:
- Getting the k<sup>th</sup> from last node - Have two pointers, where one is k nodes ahead of the other. When the node ahead reaches the end, the other node is k nodes behind.
- Detecting cycles - Have two pointers, where one pointer increments twice as much as the other, if the two pointers meet, means that there is a cycle.
- Getting the middle node - Have two pointers, where one pointer increments twice as much as the other. When the faster node reaches the end of the list, the slower node will be at the middle.
- Be familiar with the following routines because many linked list questions make use of one or more of these routines in the solution:
- Counting the number of nodes in the linked list.
- Reversing a linked list in-place.
- Finding the middle node of the linked list using fast/slow pointers.
- Merging two lists together.
- Corner cases:
- Single node.
- Two nodes.
- Cycle in linked list - Clarify whether there can be a cycle in the list? Usually the answer is no.
#### Practice Questions
- [Reverse a Linked List](https://leetcode.com/problems/reverse-linked-list/)
- [Detect Cycle in a Linked List](https://leetcode.com/problems/linked-list-cycle/)
- [Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/)
- [Merge K Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/)
- [Remove Nth Node From End Of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/)
- [Reorder List](https://leetcode.com/problems/reorder-list/)
## Math
- If code involves division or modulo, remember to check for division or modulo by 0 case.
- When a question involves "a multiple of a number", perhaps modulo might be useful.
- Check for and handle overflow/underflow if you are using a typed language like Java and C++. At the very least, mention that overflow/underflow is possible and ask whether you need to handle it.
- Consider negative numbers and floating point numbers. This may sound obvious, but under interview pressure, many obvious cases go unnoticed.
- If the question asks to implement an operator such as power, squareroot or division and want it to be faster than O(n), binary search is usually the approach to go.
- Some common formulas:
- Sum of 1 to N = (n+1) * n/2
- Sum of GP = 2<sup>0</sup> + 2<sup>1</sup> + 2<sup>2</sup> + 2<sup>3</sup> + ... 2<sup>n</sup> = 2<sup>n+1</sup> - 1
- Permutations of N = N! / (N-K)!
- Combinations of N = N! / (K! * (N-K)!)
#### Practice Questions
- [Pow(x, n)](https://leetcode.com/problems/powx-n/)
- [Sqrt(x)](https://leetcode.com/problems/sqrtx/)
- [Integer to English Words](https://leetcode.com/problems/integer-to-english-words/)
## Matrix
- A matrix is a 2-dimensional array. Questions involving matrices are usually related to dynamic programming or graph traversal.
- Corner cases:
- Empty matrix. Check that none of the arrays are 0 length.
- 1 x 1 matrix.
- Matrix with only one row or column.
- For questions involving traversal or dynamic programming, you almost always want to make a copy of the matrix with the same dimensions that is initialized to empty values to store the visited state or dynamic programming table. Be familiar with such a routine:
```py
rows, cols = len(matrix), len(matrix[0])
copy = [[0 for _ in range(cols)] for _ in range(rows)]
```
- Many grid-based games can be modeled as a matrix, such as Tic-Tac-Toe, Sudoku, Crossword, Connect 4, Battleship, etc. It is not uncommon to be asked to verify the winning condition of the game. For games like Tic-Tac-Toe, Connect 4 and Crosswords, where verification has to be done vertically and horizontally, one trick is to write code to verify the matrix for the horizontal cells, transpose the matrix and reuse the logic for horizontal verification to verify originally vertical cells (which are now horizontal).
- Transposing a matrix in Python is simply:
```py
transposed_matrix = zip(*matrix)
```
#### Practice Questions
- [Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/)
- [Spiral Matrix](https://leetcode.com/problems/spiral-matrix/)
- [Rotate Image](https://leetcode.com/problems/rotate-image/)
- [Word Search](https://leetcode.com/problems/word-search/)
## Recursion
- Remember to always define a base case so that your recursion will end.
- Useful for permutation, generating all combinations and tree-based questions.
- Be familiar with how to generate all permutations of a sequence as well as how to handle duplicates.
- Recursion implicitly uses a stack. Hence all recursive approaches can be rewritten iteratively using a stack.
- Beware of cases where the recursion level goes too deep and causes a stack overflow (the default limit in Python is 1000).
- Recursion will never be O(1) space complexity because a stack is involved unless there is [tail-call optimization](https://stackoverflow.com/questions/310974/what-is-tail-call-optimization). Do find out if your chosen language supports tail-call optimization.
#### Practice Questions
- [Subsets](https://leetcode.com/problems/subsets/) and [Subsets II](https://leetcode.com/problems/subsets-ii/)
- [Strobogrammatic Number II](https://leetcode.com/problems/strobogrammatic-number-ii/)
## String
- Please read the above tips on [Sequence](#sequence) because they apply to strings too.
- Corner cases:
- Strings with only one distinct character.
- Ask about input character set and case sensitivity. Usually the characters are limited to lower case Latin characters, i.e. a-z.
- When you need to compare strings where the order isn't important (like anagram), you may consider using a hash map as a counter. If your language has a built-in `Counter` class like Python, ask to use that instead.
- If you need to keep a counter of characters, a common mistake to make is to say that the space complexity required for the counter is O(n). The space required for a counter is O(1) not O(n), because the upper bound is the range of characters which is usually a fixed constant of 26 when the input set is just lower case Latin characters.
- Common data structures for looking up strings efficiently:
- [Trie / Prefix Tree](https://www.wikiwand.com/en/Trie)
- [Suffix Tree](https://www.wikiwand.com/en/Suffix_tree)
- Common string algorithms:
- [Rabin Karp](https://www.wikiwand.com/en/Rabin%E2%80%93Karp_algorithm) for efficient searching of substring using a rolling hash.
- [KMP](https://www.wikiwand.com/en/Knuth%E2%80%93Morris%E2%80%93Pratt_algorithm) for efficient searching of substring.
#### Non-repeating Characters
- Use a 26-bit bitmask to indicate which lower case latin characters are inside the string.
```py
mask = 0
for c in set(word):
mask |= (1 << (ord(c) - ord('a')))
```
- To determine if two strings have common characters, perform `&` on the two bitmasks and if the result is non-zero, the two strings do have common characters: `mask_a & mask_b > 0`.
#### Anagram
- An anagram is direct word switch or word play, the result of rearranging the letters of a word or phrase to produce a new word or phrase, using all the original letters exactly once. In interviews, usually we are only bothered with words without spaces in them.
- Determine if two strings are anagrams:
- Sorting both strings should produce the same resulting string.
- If we map each character to a prime number and we multiply each mapped number together, anagrams should have the same multiple (prime factor decomposition).
- Frequency counting of characters will help to determine if two strings are anagrams.
#### Palindrome
- A palindrome is a word, phrase, number, or other sequence of characters which reads the same backward as forward, such as madam or racecar.
- Ways to determine if a string is a palindrome:
- Reverse the string and it should be equal to itself.
- Have two pointers at the start and end of the string, move inwards till they meet. At any point in time the characters at both pointers should match.
- The order of characters within the string matters, so hash maps are usually not helpful.
- When a question is about counting the number of palindromes, a common trick is to have two pointer that move outwards, away from the middle. Note that palindromes can be even/odd length, and that for each middle pivot position, you would need to check twice, once including the character, and once without.
- For substrings, you can terminate early once there is no match.
- For subsequences, use dynamic programming as there are overlapping subproblems. Check out [this question](https://leetcode.com/problems/longest-palindromic-subsequence/).
#### Practice Questions
- [Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/)
- [Longest Repeating Character Replacement](https://leetcode.com/problems/longest-repeating-character-replacement/)
- [Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/description/)
- [Encode and Decode Strings](https://leetcode.com/problems/encode-and-decode-strings/)
- [Valid Anagram](https://leetcode.com/problems/valid-anagram)
- [Group Anagrams](https://leetcode.com/problems/group-anagrams/)
- [Valid Parentheses](https://leetcode.com/problems/valid-parentheses)
- [Valid Palindrome](https://leetcode.com/problems/valid-palindrome/)
- [Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/)
- [Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/)
## Tree
- A tree is an undirected, connected, acyclic graph.
- Recursion is a common approach for trees. When you notice the subtree problem can be used to solve the whole problem, you should try recursion.
- When using recursion, always remember to check for the base case, usually where the node is `null`.
- When you are asked to traverse a tree by level, use depth-first search.
- Sometimes it is possible that your recursive function needs to return two values.
- If the question involves summation of nodes along the way, be sure to check whether nodes can be negative.
- You should be very familiar with writing pre-order, in-order and post-order traversal recursively. As an extension, challenge yourself by writing them iteratively. Sometimes interviewers do ask candidates for the iterative approach, especially if the candidate finishes writing the recursive approach too fast.
- Corner cases:
- Empty tree.
- Single node.
- Two nodes.
- Very skewed tree (like a linked list).
**Binary Tree**
- In-order traversal of a binary tree is insufficient to uniquely serialize a tree. Pre-order or post-order traversal is also required.
**Binary Search Tree**
- In-order traversal of a BST will give you all elements in order.
- Be very familiar with the properties of a BST and validating that a binary tree is a BST. This comes up more often than expected.
- When a question involves a BST, the interviewer is usually looking for a solution which runs faster than O(n).
#### Practice Questions
- [Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/)
- [Same Tree](https://leetcode.com/problems/same-tree/)
- [Invert/Flip Binary Tree](https://leetcode.com/problems/invert-binary-tree/)
- [Binary Tree Maximum Path Sum](https://leetcode.com/problems/binary-tree-maximum-path-sum/)
- [Binary Tree Level Order Traversal](https://leetcode.com/problems/binary-tree-level-order-traversal/)
- [Serialize and Deserialize Binary Tree](https://leetcode.com/problems/serialize-and-deserialize-binary-tree/)
- [Subtree of Another Tree](https://leetcode.com/problems/subtree-of-another-tree/)
- [Construct Binary Tree from Preorder and Inorder Traversal](https://leetcode.com/problems/construct-binary-tree-from-preorder-and-inorder-traversal/)
- [Validate Binary Search Tree](https://leetcode.com/problems/validate-binary-search-tree/)
- [Kth Smallest Element in a BST](https://leetcode.com/problems/kth-smallest-element-in-a-bst/)
- [Lowest Common Ancestor of BST](https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-search-tree/)
## Trie
- Tries are special trees (prefix trees) that make searching and storing strings more efficient. Tries have many practical applications such as for searching and autocomplete. It will be helpful to know these common applications so that you can easily identify when a problem can be solved efficiently using a trie.
- Sometimes preprocessing a dictionary of words (given in a list) into a trie will improve the efficiency when searching for a word of length k among n words. Searching becomes O(k) instead of O(n).
- LeetCode has written a [very comprehensive article](https://leetcode.com/articles/implement-trie-prefix-tree/) on tries which you are highly encouraged to read.
- Be familiar with implementing a `Trie` class and its `add`, `remove` and `search` methods from scratch.
#### Practice Questions
- [Implement Trie (Prefix Tree)](https://leetcode.com/problems/implement-trie-prefix-tree)
- [Add and Search Word](https://leetcode.com/problems/add-and-search-word-data-structure-design)
- [Word Search II](https://leetcode.com/problems/word-search-ii/)
## Heap
- If you see a top/lowest K being mentioned in the question, it is usually a signal that a heap can be used to solve the problem.
- If you require the top K elements use a Min Heap of size K. Iterate through each element, pushing it into the heap. Whenever the heap size exceeds K, remove the minimum element, that will guarantee that you have the K largest elements.
#### Practice Questions
- [Merge K Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/)
- [Top K Frequent Elements](https://leetcode.com/problems/top-k-frequent-elements/)
- [Find Median from Data Stream](https://leetcode.com/problems/find-median-from-data-stream/)
###### References
- http://blog.triplebyte.com/how-to-pass-a-programming-interview
- https://quip.com/q41AA3OmoZbC
- http://www.geeksforgeeks.org/must-do-coding-questions-for-companies-like-amazon-microsoft-adobe/

63
algorithms/array.md Normal file
View File

@@ -0,0 +1,63 @@
Arrays
==
- In an arrays of arrays, e.g. given `[[], [1, 2, 3], [4, 5], [], [], [6, 7], [8], [9, 10], [], []]`, print: `1, 2, 3, 4, 5, 6, 7, 8, 9, 10`.
- Implement an iterator that supports `hasNext()`, `next()` and `remove()` methods.
- Given a list of item prices, find all possible combinations of items that sum a particular value `K`.
- Paginate an array with constraints, such as skipping certain items.
- Implement a circular buffer using an array.
- Given array of arrays, sort them in ascending order.
- Given an array of integers, print out a histogram of using said array; include a base layer (all stars)
- E.g. `[5, 4, 0, 3, 4, 1]`
```
*
** *
** **
** **
** ***
******
```
- Given an array and an index, find the product of the elements of the array except the element at that index.
- Given a set of rectangles represented by a height and an interval along the y-axis, determine the size of its union.
- Given 2 separate arrays, write a method to find the values that exist in both arrays and return them.
- Given an array of integers find whether there is a sub-sequence that sums to 0 and return it.
- E.g. `[1, 2, -3, 1]` => `[1, 2, -3]` or `[2, -3, 1]`.
- Given an input array and another array that describes a new index for each element, mutate the input array so that each element ends up in their new index. Discuss the runtime of the algorithm and how you can be sure there would not be any infinite loops.
- Given an array of non-negative numbers, find continuous subarray with sum to S.
- [Source](http://blog.gainlo.co/index.php/2016/06/01/subarray-with-given-sum/).
- Given an array of numbers list out all triplets that sum to 0. Do so with a running time of less than O(n^3).
- [Source](http://blog.gainlo.co/index.php/2016/07/19/3sum/).
- Given an array of numbers list out all quadruplets that sum to 0. Do so with a running time of less than O(n^4).
- Given an array of integers, move all the zeroes to the end while preserving the order of the other elements. You have to do it in-place and are not allowed to use any extra storage.
- Given a list of people, and a function `knows(a, b)` that returns `true`/`false` if person `a` knows the person `b`. Write a function that finds a VIP, which everybody knows and he doesn't know anybody else.
- Given an array of integers, find the subarray with the largest sum. Can you do it in linear time.
- Maximum subarray sum problem.
- You have an array with the heights of an island (at point 1, point 2 etc) and you want to know how much water would remain on this island (without flowing away).
- Trapping rain water question.
- Given a sequence of tasks like `A, B, C` (means 3 different tasks), and a cold time, which means you need to wait for that much time to start the next same task, output the best task-finishing sequence.
- E.g. input: `AAABBB, 2`, output: `AB_AB_AB` ( `_` represents do nothing and wait)
- You are given a list of dominoes. Determine if any two of those dominoes add up to `[6, 6]`.
- E.g. `[1, 4]` + `[5, 2]`).
- Given an array containing only digits `0-9`, add one to the number and return the array.
- E.g. Given `[1, 4, 2, 1]` which represents `1421`, return `[1, 4, 2, 2]` which represents `1422`.
- Find the second maximum value in an array.
- Given an array, find the longest arithmetic progression.
- Rotate an array by an offset of k.
- Remove duplicates in an unsorted array where the duplicates are at a distance of k or less from each other.
- Given an unsorted list of integers, return true if the list contains any duplicates within k indices of each element. Do it faster than O(n^2).
- Given an unsorted list of integers, return true if the list contains any fuzzy duplicates within k indices of each element. A fuzzy duplicate is another integer within d of the original integer. Do it faster than O(n^2).
- E.g. If d = 4, then 6 is a fuzzy duplicate of 3 but 8 is not.
- Say you have an unordered list of numbers ranging from 1 to n, and one of the numbers is removed, how do you find that number? What if two numbers are removed?
- Given an array of string, find the duplicated elements.
- [Source](http://blog.gainlo.co/index.php/2016/05/10/duplicate-elements-of-an-array/).
- Given an array of integers, find a maximum sum of non-adjacent elements.
- E.g. `[1, 0, 3, 9, 2]` should return `10 (1 + 9)`.
- [Source](http://blog.gainlo.co/index.php/2016/12/02/uber-interview-question-maximum-sum-non-adjacent-elements/)
- Given an array of integers, modify the array by moving all the zeros to the end (right side). The order of other elements doesnt matter.
- E.g. `[1, 2, 0, 3, 0, 1, 2]`, the program can output `[1, 2, 3, 1, 2, 0, 0]`.
- [Source](http://blog.gainlo.co/index.php/2016/11/18/uber-interview-question-move-zeroes/).
- Given an array, return the length of the longest increasing contiguous subarray.
- E.g., `[1, 3, 2, 3, 4, 8, 7, 9]`, should return `4` because the longest increasing array is `[2, 3, 4, 8]`.
- [Source](http://blog.gainlo.co/index.php/2017/02/02/uber-interview-questions-longest-increasing-subarray/).

View File

@@ -0,0 +1,27 @@
Dynamic Programming
==
- Given a flight itinerary consisting of starting city, destination city, and ticket price (2D list) - find the optimal price flight path to get from start to destination. (A variation of Dynamic Programming Shortest Path)
- Given some coin denominations and a target value `M`, return the coins combination with the minimum number of coins.
- Time complexity: `O(MN)`, where N is the number of distinct type of coins.
- Space complexity: `O(M)`.
- Given a set of numbers in an array which represent number of consecutive days of AirBnb reservation requested, as a host, pick the sequence which maximizes the number of days of occupancy, at the same time, leaving at least a 1 day gap in-between bookings for cleaning.
- Problem reduces to finding the maximum sum of non-consecutive array elements.
- E.g.
~~~
// [5, 1, 1, 5] => 10
The above array would represent an example booking period as follows -
// Dec 1 - 5
// Dec 5 - 6
// Dec 6 - 7
// Dec 7 - 12
The answer would be to pick Dec 1-5 (5 days) and then pick Dec 7-12 for a total of 10 days of occupancy, at the same time, leaving at least 1 day gap for cleaning between reservations.
Similarly,
// [3, 6, 4] => 7
// [4, 10, 3, 1, 5] => 15
~~~
- How many string representations are there for an integer where `a->1, b->2, ... z->26`.
- E.g. `26 => 2`. Because `26` can be encoded as `"z"` and `"bf"`.
- Given a list of denominations (e.g., `[1, 2, 5]` means you have coins worth $1, $2, and $5) and a target number `k`, find all possible combinations, if any, of coins in the given denominations that add up to `k`. You can use coins of the same denomination more than once.

7
algorithms/geometry.md Normal file
View File

@@ -0,0 +1,7 @@
Geometry
==
- You have a plane with lots of rectangles on it, find out how many of them intersect.
- Which data structure would you use to query the k-nearest points of a set on a 2D plane?
- Given many points, find k points that are closest to the origin.
- How would you triangulate a polygon?

12
algorithms/graph.md Normal file
View File

@@ -0,0 +1,12 @@
Graph
==
- Given a list of sorted words from an alien dictionary, find the order of the alphabet.
- Alien Dictionary Topological Sort question.
- Find if a given string matches any path in a labeled graph. A path may contain cycles.
- Given a friendship graph (an undirected graph where nodes represent people and edges means two people know each other), find all your 2nd degree connections (friends friends). Output these 2nd degree connections ranked by number of common friends (i.e 1st degree connections) with you, (example: if 2nd degree connection A has 10 common friends (1st degree connections) with you but 2nd degree connection B has 8 common friends (1st degree connections) with you, then A should be ranked first).
- Given a bipartite graph, separate the vertices into two sets.
- Given a list of email addresses, and a similarity function which says whether two email addresses are similar, write a function to separate the list into sets of email addresses that are similar to each other.
- You are a thief trying to sneak across a rectangular field. There are alarms placed on the fields and they each have a circular sensing radius which will trigger if anyone steps into it. Each alarm may not have the same radius. Determine if you can get from one end of the field to the other end.
- Given a graph and two nodes, determine if there exists a path between them.
- Determine if a cycle exists in the graph.

7
algorithms/hash-table.md Normal file
View File

@@ -0,0 +1,7 @@
Hash Table
==
- Describe an implementation of a least-used cache, and big-O notation of it.
- A question involving an API's integration with hash map where the buckets of hash map are made up of linked lists.
- Implement data structure `Map` storing pairs of integers (key, value) and define following member functions in O(1) runtime: `void insert(key, value)`, `void delete(key)`, `int get(key)`, `int getRandomKey()`.
- [Source](http://blog.gainlo.co/index.php/2016/08/14/uber-interview-question-map-implementation/).

5
algorithms/heap.md Normal file
View File

@@ -0,0 +1,5 @@
Heap
==
- Merge `K` sorted lists together into a single list.
- Given a stream of integers, write an efficient function that returns the median value of the integers.

28
algorithms/interval.md Normal file
View File

@@ -0,0 +1,28 @@
Interval
==
- Given a list of schedules, provide a list of times that are available for a meeting.
```
[
[[4,5], [6,10], [12,14]],
[[4,5], [5,9], [13,16]],
[[11,14]]
]
Example Output:
[[0,4], [11,12], [16,23]]
```
- You have a number of meetings (with their start and end times). You need to schedule them using the minimum number of rooms. Return the list of meetings in every room.
- Interval ranges:
- Given 2 interval ranges, create a function to tell me if these ranges intersect. Both start and end are inclusive: `[start, end]`
- E.g. `[1, 4]` and `[5, 6]` => `false`
- E.g. `[1, 4]` and `[3, 6]` => `true`
- Given 2 interval ranges that intersect, now create a function to merge the 2 ranges into a single continuous range.
- E.g. `[1, 4]` and `[3, 6]` => `[1, 6]`
- Now create a function that takes a group of unsorted, unorganized intervals, merge any intervals that intersect and sort them. The result should be a group of sorted, non-intersecting intervals.
- Now create a function to merge a new interval into a group of sorted, non-intersecting intervals. After the merge, all intervals should remain
non-intersecting.
- Given a list of meeting times, check if any of them overlap. The follow-up question is to return the minimum number of rooms required to accommodate all the meetings.
- [Source](http://blog.gainlo.co/index.php/2016/07/12/meeting-room-scheduling-problem/)
- If you have a list of intervals, how would you merge them?
- E.g. `[1, 3], [8, 11], [2, 6]` => `[1, 6], [8-11]`

13
algorithms/linked-list.md Normal file
View File

@@ -0,0 +1,13 @@
Linked List
==
- Given a linked list, in addition to the next pointer, each node has a child pointer that can point to a separate list. With the head node, flatten the list to a single-level linked list.
- [Source](http://blog.gainlo.co/index.php/2016/06/12/flatten-a-linked-list/)
- Reverse a singly linked list. Implement it recursively and iteratively.
- Convert a binary tree to a doubly circular linked list.
- Implement an LRU cache with O(1) runtime for all its operations.
- Check distance between values in linked list.
- A question involving an API's integration with hash map where the buckets of hash map are made up of linked lists.
- Given a singly linked list (a list which can only be traversed in one direction), find the item that is located at 'k' items from the end. So if the list is a, b, c, d and k is 2 then the answer is 'c'. The solution should not search the list twice.
- How can you tell if a Linked List is a Palindrome?
- Implement a LRU cache with O(1) runtime for all its operations.

20
algorithms/math.md Normal file
View File

@@ -0,0 +1,20 @@
Math
==
- Create a square root function.
- Given a string such as "123" or "67", write a function to output the number represented by the string without using casting.
- Make a program that can print out the text form of numbers from 1 - 1000 (ex. 20 is "twenty", 105 is "one hundred and five").
- Write a function that parses Roman numerals.
- E.g. `XIV` returns `14`.
- Write in words for a given digit.
- E.g. `123` returns `one hundred and twenty three`.
- Given a number `N`, find the largest number just smaller than `N` that can be formed using the same digits as `N`.
- Compute the square root of `N` without using any existing functions.
- Given numbers represented as binary strings, and return the string containing their sum.
- E.g. `add('10010', '101')` returns `'10111'`.
- Take in an integer and return its english word-format.
- E.g. 1 -> "one", -10,203 -> "negative ten thousand two hundred and three".
- Write a function that returns values randomly, according to their weight. Suppose we have 3 elements with their weights: A (1), B (1) and C (2). The function should return A with probability 25%, B with 25% and C with 50% based on the weights.
- [Source](http://blog.gainlo.co/index.php/2016/11/11/uber-interview-question-weighted-random-numbers/)
- Given a number, how can you get the next greater number with the same set of digits?
- [Source](http://blog.gainlo.co/index.php/2017/01/20/arrange-given-numbers-to-form-the-biggest-number-possible/)

18
algorithms/matrix.md Normal file
View File

@@ -0,0 +1,18 @@
Matrix
==
- You're given a 3 x 3 board of a tile puzzle, with 8 tiles numbered 1 to 8, and an empty spot. You can move any tile adjacent to the empty spot, to the empty spot, creating an empty spot where the tile originally was. The goal is to find a series of moves that will solve the board, i.e. get `[[1, 2, 3], [4, 5, 6], [7, 8, - ]]` where - is the empty tile.
- Boggle implementation. Given a dictionary, and a matrix of letters, find all the words in the matrix that are in the dictionary. You can go across, down or diagonally.
- The values of the matrix will represent numbers of carrots available to the rabbit in each square of the garden. If the garden does not have an exact center, the rabbit should start in the square closest to the center with the highest carrot count. On a given turn, the rabbit will eat the carrots available on the square that it is on, and then move up, down, left, or right, choosing the the square that has the most carrots. If there are no carrots left on any of the adjacent squares, the rabbit will go to sleep. You may assume that the rabbit will never have to choose between two squares with the same number of carrots. Write a function which takes a garden matrix and returns the number of carrots the rabbit eats. You may assume the matrix is rectangular with at least 1 row and 1 column, and that it is populated with non-negative integers. For example,
- Example: `[[5, 7, 8, 6, 3], [0, 0, 7, 0, 4], [4, 6, 3, 4, 9], [3, 1, 0, 5, 8]]` should return `27`.
- Print a matrix in a spiral fashion.
- In the Game of life, calculate how to compute the next state of the board. Follow up was to do it if there were memory constraints (board represented by a 1 TB file).
- Grid Illumination: Given an NxN grid with an array of lamp coordinates. Each lamp provides illumination to every square on their x axis, every square on their y axis, and every square that lies in their diagonal (think of a Queen in chess). Given an array of query coordinates, determine whether that point is illuminated or not. The catch is when checking a query all lamps adjacent to, or on, that query get turned off. The ranges for the variables/arrays were about: 10^3 < N < 10^9, 10^3 < lamps < 10^9, 10^3 < queries < 10^9.
- You are given a matrix of integers. Modify the matrix such that if a row or column contains a 0, make the values in the entire row or column 0.
- Given an N x N matrix filled randomly with different colors (no limit on what the colors are), find the total number of groups of each color - a group consists of adjacent cells of the same color touching each other.
- You have a 4 x 4 board with characters. You need to write a function that finds if a certain word exists in the board. You can only jump to neighboring characters (including diagonally adjacent).
- Count the number of islands in a binary matrix of 0's and 1's.
- Check a 6 x 7 Connect 4 board for a winning condition.
- Given a fully-filled Sudoku board, check whether fulfills the Sudoku condition.
- Implement a function that checks if a player has won tic-tac-toe.
- Given an N x N matrix of 1's and 0's, figure out if all of the 1's are connected.

4
algorithms/oop.md Normal file
View File

@@ -0,0 +1,4 @@
Object-Oriented Programming
==
- How would you design a chess game? What classes and objects would you use? What methods would they have?

12
algorithms/permutation.md Normal file
View File

@@ -0,0 +1,12 @@
Permutation
==
- You are given a 7 digit phone number, and you should find all possible letter combinations based on the digit-to-letter mapping on numeric pad and return only the ones that have valid match against a given dictionary of words.
- Give all possible letter combinations from a phone number.
- Generate all subsets of a string.
- Print all possible `N` pairs of balanced parentheses.
- E.g. when `N` is `2`, the function should print `(())` and `()()`.
- E.g. when `N` is `3`, we should get `((()))`, `(()())`, `(())()`, `()(())`, `()()()`.
- [Source](http://blog.gainlo.co/index.php/2016/12/23/uber-interview-questions-permutations-parentheses/)
- Given a list of arrays, return a list of arrays, where each array is a combination of one element in each given array.
- E.g. If the input is `[[1, 2, 3], [4], [5, 6]]`, the output should be `[[1, 4, 5], [1, 4, 6], [2, 4, 5], [2, 4, 6], [3, 4, 5], [3, 4, 6]]`.

4
algorithms/queue.md Normal file
View File

@@ -0,0 +1,4 @@
Queue
==
- Implement a Queue class from scratch with an existing bug, the bug is that it cannot take more than 5 elements.

View File

@@ -0,0 +1,18 @@
Sorting and Searching
==
- Sorting search results on a page given a certain set of criteria.
- Sort a list of numbers in which each number is at a distance `K` from its actual position.
- Given an array of integers, sort the array so that all odd indexes are greater than the even indexes.
- Given users with locations in a list and a logged-in user with locations, find their travel buddies (people who shared more than half of your locations).
- Search for an element in a sorted and rotated array.
- [Source](http://blog.gainlo.co/index.php/2017/01/12/rotated-array-binary-search/)
- Sort a list where each element is no more than k positions away from its sorted position.
- If you have `N` revisions of a program, write a program that will find and return the first bad revision given a `isBad(revision i)` function.
- Search for an item in a sorted, but rotated, array.
- Merge two sorted lists together.
- Given a list of numbers and a function that returns Low, Medium, or High, sort the list by Lows, then Mediums, then Highs.
- Give 3 distinct algorithms to find the K largest values in a list of N items.
- Find the minimum element in a sorted rotated array in faster than O(n) time.
- Write a function that takes a number as input and outputs the biggest number with the same set of digits.
- [Source](http://blog.gainlo.co/index.php/2017/01/20/arrange-given-numbers-to-form-the-biggest-number-possible/)

8
algorithms/stack.md Normal file
View File

@@ -0,0 +1,8 @@
Stack
==
- Implementation of an interpreter for a small language that does multiplication/addition/etc.
- Design a `MinStack` data structure that supports a `min()` operation that returns the minimum value in the stack in O(1) time.
- Write an algorithm to determine if all of the delimiters in an expression are matched and closed.
- E.g. `{ac[bb]}`, `[dklf(df(kl))d]{}` and `{[[[]]]}` are matched. But `{3234[fd` and `{df][d}` are not.
- [Source](http://blog.gainlo.co/index.php/2016/09/30/uber-interview-question-delimiter-matching/)

61
algorithms/string.md Normal file
View File

@@ -0,0 +1,61 @@
String
==
- Output list of strings representing a page of hostings given a list of CSV strings.
- Given a list of words, find the word pairs that when concatenated form a palindrome.
- Find the most efficient way to identify what character is out of place in a non-palindrome.
- Implement a simple regex parser which, given a string and a pattern, returns a boolean indicating whether the input matches the pattern. By simple, we mean that the regex can only contain special character: `*` (star), `.` (dot), `+` (plus). The star means that there will be zero or more of previous character in that place in the pattern. The dot means any character for that position. The plus means one or more of previous character in that place in the pattern.
- Find all words from a dictionary that are x edit distance away.
- Given a string IP and number n, print all CIDR addresses that cover that range.
- Write a function called `eval`, which takes a string and returns a boolean. This string is allowed 6 different characters: `0`, `1`, `&`, `|`, `(`, and `)`. `eval` should evaluate the string as a boolean expression, where `0` is `false`, `1` is `true`, `&` is an `and`, and `|` is an `or`.
- E.g `"(0 | (1 | 0)) & (1 & ((1 | 0) & 0))"`
- Given a pattern string like `"abba"` and an input string like `"redbluebluered"`, return `true` if and only if there's a one to one mapping of letters in the pattern to substrings of the input.
- E.g. `"abba"` and `"redblueredblue"` should return `true`.
- E.g. `"aaaa"` and `"asdasdasdasd"` should return `true`.
- E.g. `"aabb"` and `"xyzabcxzyabc"` should return `false`.
- If you received a file in chunks, calculate when you have the full file. Quite an open-ended question. Can assume chunks come with start and end, or size, etc.
- Given a list of names (strings) and the width of a line, design an algorithm to display them using the minimum number of lines.
- Design a spell-checking algorithm.
- Count and say problem.
- Longest substring with `K` unique characters.
- [Source](http://blog.gainlo.co/index.php/2016/04/12/find-the-longest-substring-with-k-unique-characters/)
- Given a set of random strings, write a function that returns a set that groups all the anagrams together.
- [Source](http://blog.gainlo.co/index.php/2016/05/06/group-anagrams/)
- Given a string, find the longest substring without repeating characters. For example, for string `'abccdefgh'`, the longest substring is `'cdefgh'`.
- [Source](http://blog.gainlo.co/index.php/2016/10/07/facebook-interview-longest-substring-without-repeating-characters/)
- Given a string, return the string with duplicate characters removed.
- How many string representations are there for an integer where `a->1, b->2, ... z->26`.
- E.g. `126` can be `'az'` or `'abf'`.
- Write a function that receives a regular expression (allowed chars = from `'a'` to `'z'`, `'*'`, `'.'`) and a string containing lower case english alphabet characters and return `true` or `false` whether the string matches the regex.
- E.g. `'ab*a'`, `'abbbbba'` => `true`.
- E.g. `'ab*b.'`, `'aba'` => `true`.
- E.g. `'abc*'`, `'acccc'` => `false`.
- Given a rectangular grid with letters, search if some word is in the grid.
- Given two strings representing integer numbers (`'123'` , `'30'`) return a string representing the sum of the two numbers: `'153'`.
- Given a really big file with a lots of Facebook posts, find the ten most-used words.
- A professor wants to see if two students have cheated when writing a paper. Design a function `hasCheated(String s1, String s2, int N)` that evaluates to `true` if two strings have a common substring of length `N`.
- Follow up: Assume you don't have the possibility of using `String.contains()` and `String.substring()`. How would you implement this?
- Print all permutations of a given string.
- Parse a string containing numbers and `'+'`, `'-'` and parentheses. Evaluate the expression. `-2+(3-5)` should return `-4`.
- Output a substring with at most `K` unique characters.
- E.g. `'aabc'` and `k` = 2 => `'aab'`.
- Ensure that there are a minimum of `N` dashes between any two of the same characters of a string.
- E.g. `n = 2, string = 'ab-bcdecca'` => `'ab--bcdec--ca'`.
- Find the longest palindrome in a string.
- Give the count and the number following in the series.
- E.g. `1122344`, next: `21221324`, next: `12112211121214`.
- Count and say problem.
- Compress a string by grouping consecutive similar questions together:
- E.g. `'aaabbbcc' => `'a3b3c2'`.
- You have a string consisting of open and closed parentheses, but parentheses may be imbalanced. Make the parentheses balanced and return the new string.
- Given a set of strings, return the smallest subset that contains prefixes for every string.
- E.g. `['foo', 'foog', 'food', 'asdf']` => `['foo', 'asdf']`.
- Write a function that would return all the possible words generated when using a phone (pre-smartphone era) numpad to type.
- Given a dictionary and a word, find the minimum number of deletions needed on the word in order to make it a valid word.
- [Source](http://blog.gainlo.co/index.php/2016/04/29/minimum-number-of-deletions-of-a-string/)
- How to check if a string contains an anagram of another string?
- [Source](http://blog.gainlo.co/index.php/2016/04/08/if-a-string-contains-an-anagram-of-another-string/)
- Find all k-lettered words from a string.
- Given a string of open and close parentheses, find the minimum number of edits needed to balance a string of parentheses.
- Run length encoding - Write a string compress function that returns `'R2G1B1'` given `'RRGB'`.
- Write a function that finds all the different ways you can split up a word into a concatenation of two other words.

89
algorithms/topics.md Normal file
View File

@@ -0,0 +1,89 @@
Topics
==
## Arrays
## Strings
- Prefix trees (Tries)
- Suffix trees
- Suffix arrays
- KMP
- Rabin-Karp
- Boyer-Moore
## Sorting
- Bubble sort
- Insertion sort
- Merge sort
- Quick sort
- Selection sort
- Bucket sort
- Radix sort
- Counting sort
## Linked Lists
## Stacks
## Queues
## Hash tables
- Collision resolution algorithms
## Trees
- BFS
- DFS (inorder, postorder, preorder)
- Height
## Binary Search Trees
- Insert node
- Delete a node
- Find element in BST
- Find min, max element in BST
- Get successor element in tree
- Check if a binary tree is a BST or not
## Heaps / Priority Queues
- Insert
- Bubble up
- Extract max
- Remove
- Heapify
- Heap sort
## Graphs
- Various implementations
- Adjacency matrix
- Adjacency list
- Adjacency map
- Single-source shortest path
- Dijkstra
- Bellman-Ford
- Topo sort
- MST
- Prim algorithm
- Kruskal's algorithm
- Union Find Data Structure
- Count connected components in a graph
- List strongly connected components in a graph
- Check for bipartite graph
## Dynamic Programming
- Count Change
- 0-1 Knapsack
## System Design
- http://www.hiredintech.com/system-design/
- https://www.quora.com/How-do-I-prepare-to-answer-design-questions-in-a-technical-interview?redirected_qid=1500023
- http://blog.gainlo.co/index.php/2015/10/22/8-things-you-need-to-know-before-system-design-interviews/
- https://github.com/donnemartin/system-design-primer
- https://github.com/jwasham/coding-interview-university/blob/master/extras/cheat%20sheets/system-design.pdf

37
algorithms/tree.md Normal file
View File

@@ -0,0 +1,37 @@
Tree
==
- Find the height of a tree.
- Find the longest path from the root to leaf in a tree.
- Find the deepest left leaf of a tree.
- Print all paths of a binary tree.
- [Source](http://blog.gainlo.co/index.php/2016/04/15/print-all-paths-of-a-binary-tree/)
- Second largest element of a BST.
- [Source](http://blog.gainlo.co/index.php/2016/06/03/second-largest-element-of-a-binary-search-tree/)
- Given a binary tree and two nodes, how to find the common ancestor of the two nodes?
- [Source](http://blog.gainlo.co/index.php/2016/07/06/lowest-common-ancestor/)
- Find the lowest common ancestor of two nodes in a binary search tree.
- Print the nodes in an n-ary tree level by level, one printed line per level.
- Given a directory of files and folders (and relevant functions), how would you parse through it to find equivalent files?
- Write a basic file system and implement the commands ls, pwd, mkdir, create, rm, cd, cat, mv.
- Compute the intersection of two binary search trees.
- Given a tree, where the parent has any number of nodes and each node has a number, return the average of all the nodes on each level in an array.
- Given a binary tree, output all the node to leaf paths of it.
- Given a string of characters without spaces, is there a way to break the string into valid words without leftover characters?
- Print a binary tree level by level.
- Determine if a binary tree is "complete" (i.e, if all leaf nodes were either at the maximum depth or max depth-1, and were 'pressed' along the left side of the tree).
- Find the longest path in a binary tree. The path may start and end at any node.
- Determine if a binary tree is a BST.
- Given a binary tree, serialize it into a string. Then deserialize it.
- Print a binary tree by column.
- Given a node, find the next element in a BST.
- Find the shortest subtree that consist of all the deepest nodes. The tree is not binary.
- Print out the sum of each row in a binary tree.
- Pretty print a JSON object.
- Convert a binary tree to a doubly circular linked list.
- Find the second largest number in a binary tree.
- Given a tree, find the longest branch.
- Convert a tree to a linked list.
- Given two trees, write code to find out if tree A is a subtree of tree B.
- Deepest node in a tree.
- [Source](http://blog.gainlo.co/index.php/2016/04/26/deepest-node-in-a-tree/)