Coding Interview Patterns

Ace your homework & exams now with Quizwiz!

Post-Order Traversal

left, right, root

In-Order Traversal

left, root, right

Maximum Subarray: Given an integer array nums, find the subarray which has the largest sum and return the sum.

Create two running counters (current, max)—run through the nums, add each element to current, and update max when current > max. If current < 0, then reset it back to zero.

Valid Anagram Given two strings s and t, return true if t is an anagram of s, and false otherwise. Input: s = "anagram", t = "nagaram" Output: true

Take both strings—use Counter() to create a hash table with each letter → frequency, and compare the two.

Two Sum: Given an array of integers nums and an integer target, return indices of the two numbers such that they add up to target.

Create a hash table of nums mapped to the index. Then, iterate through nums and check whether target-nums[i] is in the hash table, and if it is at a different index return the two indices you're looking at.

Flatten a Multilevel Doubly Linked List: You are given a doubly linked list, which contains nodes that have a next pointer, a previous pointer, and an additional child pointer. This child pointer may or may not point to a separate doubly linked list, also containing these special nodes. These child lists may have one or more children of their own, and so on, to produce a multilevel data structure as shown in the example below. Given the head of the first level of the list, flatten the list so that all the nodes appear in a single-level, doubly linked list. Let curr be a node with a child list. The nodes in the child list should appear after curr and before curr.next in the flattened list. Return the head of the flattened list. The nodes in the list must have all of their child pointers set to null.

If you invert this multilevel list on its size, you get a binary tree (with child as the left child and next as the right child). You're going to do a DFS iteratively—keep a pointer to the previous element, pop off the stack, and set the next/prev of the last element to what you just popped off. Then, add the next of the popped node and after add the child to the stack.

Design Underground System: (see description at link) https://leetcode.com/problems/design-underground-system/

Hash Table: You're going to keep two hash tables, one that tracks current riders (after they check in) and one that tracks completed rides (after check out). During checkout(), you have three options: add the total time to a list of riders that have completed this journey, sum the total time, or keep the running average. 1. Poor time complexity, because every time you retrieve the average you'd have to iterate through all the total time options for that journey to sum and divide them. 2. Better time complexity, but chance of buffer overflow—if you keep an infinite sum, it's more likely than option three to get to be too big of a value for int. 3. Best—less chance of buffer overflow, however you have a chance for compounding floating point error as you're constantly multiplying and dividing to get the running average. There are some classes like Python decimal that reduce this problem, however, so go for this option.

Design an Ordered Stream: There is a stream of inputs of (index, value) in a random order. You are given the total number of inputs. Design a stream class such that, for every insert, a certain adjacent chunk of values may be returned, but must be fully in-order if concatenated. Check problem description for more information.

Keep a global pointer/list. Start the pointer at 0 index. When you insert into the list, update the list, but if the index inserted is equal to the pointer, then start iterating forward and adding all adjacent strings to a return list. Then, return that list and update the pointer.

Decode String: Given an encoded string, return its decoded string. Input: s = "3[a]2[bc]" Output: "aaabcbc"

RECURSIVE: For this problem, we will use recursion. Iterate through the given string. If you're on a number, keep going and construct the number. Store it in n. If you hit a bracket, call a function that uses a stack to get what is inside the bracket. Then, recursively call your function on what is inside n times and add the result to your result. The base case is if the inner is the same as the given—which means you have no more brackets. STACK: Add each element of the string into a stack until you reach a closing ]. Then, keep popping off and adding to a substring until you reach an [. Once you reach the [, get the # in front of the bracket, and multiply the substring by that number. Add it to the stack, and repeat the process. Finally, join the stack into a string and return.

Remove All Adjacent Duplicates in String II: You are given a string s and an integer k, a k duplicate removal consists of choosing k adjacent and equal letters from s and removing them, causing the left and the right side of the deleted substring to concatenate together. We repeatedly make k duplicate removals on s until we no longer can. Return the final string after all such duplicate removals have been made. It is guaranteed that the answer is unique.

Stack: Iterate through your String and create a stack of the current letter/it's number of adjacent duplicates. So, for example, if you have aabbbcc your stack would be "(2a), (3b), (2c)". As soon as the top of the stack reaches a frequency of k, pop it off and continue. After you finish iterating through the whole string, convert the stack back into a string by iterating through it and using string concatenation.

Insert Delete GetRandom O(1): Implement a class that inserts, deletes, and getsRandom from a set all in constant time.

The tricky part here is finding data structure(s) that can delete and getRandom in constant time. Use a hash table AND a list of nums—to insert, add your number to both (and map the inserted index as the value in the hash table). When you delete from the list, swap the last element and the element to be deleted, and pop off the end. Then, update the hash table. All of these are in constant time.

Design a Leaderboard: Design a Leaderboard class, which has 3 functions: addScore(playerId, score): Update the leaderboard by adding score to the given player's score. If there is no player with such id in the leaderboard, add him to the leaderboard with the given score. top(K): Return the score sum of the top K players. reset(playerId): Reset the score of the player with the given id to 0 (in other words erase it from the leaderboard). It is guaranteed that the player was added to the leaderboard before calling this function. Initially, the leaderboard is empty.

There are multiple implementations for this system with different time complexities. Option #1: Use a dictionary. - Add: O(1), just add id -> score to dicrt - Top: O(n log n + k), get list of (keys, values) and sort. Then sum the largest k. - Reset: O(1), delete from dict. Option #2: Use binary search list - Add: O(log n + n), search for element in list, if you can't find it insert at that specific spot. Shift every element down. - Top: O(k), iterate on the top k elements. - Reset: O(log n + n), search for and remove. Option #3: Use a binary search tree - Add: log n, insert into tree - Top: inorder traversal, O(k) - Reset: log n, pop off and insert at bottom.

Design Browser History: Implement the BrowserHistory class: BrowserHistory(string homepage) Initializes the object with the homepage of the browser. void visit(string url) Visits url from the current page. It clears up all the forward history. string back(int steps) Move steps back in history. If you can only return x steps in the history and steps > x, you will return only x steps. Return the current url after moving back in history at most steps. string forward(int steps) Move steps forward in history. If you can only forward x steps in the history and steps > x, you will forward only x steps. Return the current url after forwarding in history at most steps.

There are multiple implementations: #1: List: Keep a list of URLs and a pointer cur - Visit: Delete from list and append to end, O(n) - Back: cur - steps, O(1) - Forward: cur + steps, O(1) #2: OrderedDict: Keep an ordered dict of values - Visit: O(1), delete key and reinsert, or popleft() function. - Forward/Back: O(n), get keys and iterate forward or back cur. #3: Doubly Linked List: Keep a doubly linked list and cur node. - Visit O(n) - delete and reinsert - Forward/Back O(steps)

Word Break: Given a string s and a dictionary of strings wordDict, return true if s can be segmented into a space-separated sequence of one or more dictionary words. Note that the same word in the dictionary may be reused multiple times in the segmentation. Input: s = "leetcode", wordDict = ["leet","code"] Output: true

We can easily convert the dictionary into a set, and just iterate through the input string—checking each substring to see if it's in the set. If it is in the set, we can = "" and restart the substring. When we finish iterating through the set, if our substring is empty, return True. However, this doesn't address the case where you have multiple options for a substring that fits into the dictionary—and if you go with the smaller one, it may be broken down incorrectly. ie: "aaaaaa", ["aaa","aaaa"] This is why we must use recursion with memoization. First check whether cur in dict, and if it is, recurse on the rest of the string. If both return true, return true. If you reach a case where cur is in the dict but there is no other substring, return true as well (base case). Also, memoize the recursive calls so you don't make any repeated ones. TIME COMPLEXITY: Without memoization, it will be 2^n as you can split the array into n+1 different choices and repeatedly recurse on all of them. With memoization, it's n^3.

Two City Scheduling: A company is planning to interview 2n people. Given the array costs where costs[i] = [aCosti, bCosti], the cost of flying the ith person to city a is aCosti, and the cost of flying the ith person to city b is bCosti. Return the minimum cost to fly every person to a city such that exactly n people arrive in each city.

You basically are looking to minimize the total sum of the array if you only pick 1 element out of the 2 each time—but you have to pick each side equally, half the time. You're going to sort by opportunity cost. If you subtract b-a of an element, you get how much more costly it would have been to pick b rather than a. Sort the array by this Greedy heuristic (you'll have some negatives) and then sum the first half of b and the rest a.

Contains Duplicate: Given an integer array nums, return true if any value appears at least twice in the array, and return false if every element is distinct.

make a set of nums, if the values in the set aren't equal to nums then return False

Pre-Order Traversal

root, left, right


Related study sets

Writing and Argumentative Essay about the Nobel Prize in Literature 100%

View Set

GUM Assessment Unit 12 lesson 13

View Set

Chapter 5: Competitive Rivalry & Competitive Dynamics

View Set

Chapter 13: Implementing Secure Mobile Solutions

View Set

Chapter 31. Nursing Care of Patients With Lower Respiratory Tract Disorders

View Set