├── 🚩 Median Finder ├── solution.cpp └── README.md ├── 🚩 Minimum Maze Path ├── solution.cpp └── README.md ├── 🚩 Process Invoker ├── solution.cpp └── README.md ├── 🚩 Bounce Back Stack ├── solution.cpp └── README.md ├── 🚩 🚩 Server Farm Naming ├── solution.cpp └── README.md ├── 🚩 Race Track ├── solution.cpp └── README.md ├── 🚩 Linked List Common Ancestor ├── linked-list-common-ancestors.png ├── solution.cpp └── README.md ├── ⭐ Binary Tree String Builder ├── README.md └── solution.cpp ├── 🚩 🚩 InterconnectedServers ├── solution.cpp └── README.md ├── ⭐ Binary Search Tree Generator ├── README.md └── solution.cpp ├── ⭐ Binary Tree Deep Copy ├── README.md └── solution.cpp ├── ⭐ ⭐ Binary Tree Siblings └── README.md ├── ⭐ ⭐ Algebraic Expression Evaluator └── README.md ├── ⭐ ⭐ Random Hash Table ├── README.md └── solution.js ├── ⭐ ⭐ ⭐ Book Index Generator ├── README.md └── solution.js ├── ⭐ ⭐ Life Events ├── README.md └── solution.js ├── ⭐ Integer Set Duplicates ├── README.md └── solution.cpp ├── ⭐ ⭐ ⭐ Palindrome Generator ├── README.md └── solution.cpp ├── 🚩 LRU Cache ├── README.md └── solution.cpp ├── README.md ├── ⭐ Balanced Binary Tree ├── README.md └── solution.cpp ├── ⭐ ⭐ ⭐ Random Linked List Deep Copy ├── README.md └── solution.cpp ├── ⭐ ⭐ ⭐ Prefix Expression Evaluator ├── README.md └── solution.cpp ├── ⭐ Min Stack ├── README.md └── solution.cpp ├── ⭐ ⭐ ⭐ Skip List Validation ├── README.md └── solution.cpp ├── ⭐ ⭐ ⭐ Image Perimeter ├── README.md └── solution.cpp ├── ⭐ ⭐ ⭐ Wedding Appetizer Table ├── README.md └── solution.cpp ├── ⭐ ⭐ Multi-Stock Sorter ├── README.md └── solution.cpp ├── ⭐ ⭐ ⭐ Image Paint Bucket Tool ├── README.md └── solution.cpp ├── ⭐ ⭐ Course Prerequisites ├── README.md └── solution.js └── ⭐ ⭐ Exam Preparedness ├── README.md └── solution.cpp /🚩 Median Finder/solution.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /🚩 Minimum Maze Path/solution.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /🚩 Process Invoker/solution.cpp: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /🚩 Bounce Back Stack/solution.cpp: -------------------------------------------------------------------------------- 1 | // TODO 2 | -------------------------------------------------------------------------------- /🚩 🚩 Server Farm Naming/solution.cpp: -------------------------------------------------------------------------------- 1 | // TODO 2 | -------------------------------------------------------------------------------- /🚩 Race Track/solution.cpp: -------------------------------------------------------------------------------- 1 | // TODO: Use priority queue to keep track of runners over time and update their values. 2 | -------------------------------------------------------------------------------- /🚩 Linked List Common Ancestor/linked-list-common-ancestors.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/simonayzman/technical-interview-questions/HEAD/🚩 Linked List Common Ancestor/linked-list-common-ancestors.png -------------------------------------------------------------------------------- /⭐ Binary Tree String Builder/README.md: -------------------------------------------------------------------------------- 1 | ### Binary Tree String Builder 2 | 3 | Given a binary tree of characters, print out all the possible strings going from the root to a leaf node. 4 | 5 | \[[Solution](solution.cpp)\] 6 | -------------------------------------------------------------------------------- /🚩 🚩 InterconnectedServers/solution.cpp: -------------------------------------------------------------------------------- 1 | // TODO: Keep track of message id and hashset of server node ids visited 2 | 3 | // TODO: Maybe necessary to keep track of message id + timestamp of creation (+ origin server node id?) 4 | -------------------------------------------------------------------------------- /⭐ Binary Search Tree Generator/README.md: -------------------------------------------------------------------------------- 1 | ### BST Generator 2 | 3 | Given an array of unique words, write a member function of the BST class that creates a balanced binary search tree with minimal height. 4 | 5 | \[[Solution](solution.cpp)\] 6 | -------------------------------------------------------------------------------- /🚩 Median Finder/README.md: -------------------------------------------------------------------------------- 1 | ### Median Finder 2 | 3 | Given two sorted arrays, find the median of what would be the super sorted array. 4 | 5 | // O(n) solution exists. O(log n) solution is possible and exists. 6 | 7 | \[[Solution](solution.cpp)\] 8 | -------------------------------------------------------------------------------- /⭐ Binary Tree Deep Copy/README.md: -------------------------------------------------------------------------------- 1 | ### Binary Tree Deep Copy 2 | 3 | Given the root of a binary tree, implement a function that performs a deep copy of the binary tree and returns the root of the newly duplicated tree. 4 | 5 | \[[Solution](solution.cpp)\] 6 | -------------------------------------------------------------------------------- /⭐ ⭐ Binary Tree Siblings/README.md: -------------------------------------------------------------------------------- 1 | ### Binary Tree Siblings 2 | 3 | Imagine you have a binary tree with nodes that also have a "next" value. 4 | 5 | Write a function that properly connects all nodes on the same level with the first available sibling on the right, if it exists. -------------------------------------------------------------------------------- /⭐ Binary Tree Deep Copy/solution.cpp: -------------------------------------------------------------------------------- 1 | Node* duplicateTree(Node* root) { 2 | if (root == NULL) { 3 | return NULL; 4 | } 5 | Node* node = new Node(root->value); 6 | node->left = duplicateTree(root->left); 7 | node->right = duplicateTree(root->right); 8 | return node; 9 | } 10 | -------------------------------------------------------------------------------- /⭐ ⭐ Algebraic Expression Evaluator/README.md: -------------------------------------------------------------------------------- 1 | ### Algebraic Expression Evaluator 2 | 3 | Imagine that you have a bunch of algebraic relationships, e.g. `A/B = 7.5`, `B/C = 2.0`. 4 | 5 | Write a function that takes in these relationships and a new relationship, e.g. `A/C`, and returns the value of the new relationship , e.g. `3.75`. -------------------------------------------------------------------------------- /🚩 Linked List Common Ancestor/solution.cpp: -------------------------------------------------------------------------------- 1 | // TODO: Start the algorithm from the first list. Start adding all the node values to a hash set. 2 | // Starting from the remaining lists, once you see a node already in the set, keep track of that 3 | // as the earliest common ancestor. Figure out cases when subsequent lists share more nodes. 4 | -------------------------------------------------------------------------------- /🚩 Race Track/README.md: -------------------------------------------------------------------------------- 1 | ### Racer problem 2 | 3 | Imagine a race with R racers and S sensors are regular intervals along the race track. Design a system that can process a "tick" (a combination of racer Rx crossing sensor Sy) at a time and that can determine who is winning at the moment in constant time. 4 | 5 | \[[Solution](solution.cpp)\] 6 | -------------------------------------------------------------------------------- /⭐ ⭐ Random Hash Table/README.md: -------------------------------------------------------------------------------- 1 | ### Random Hash Table 2 | 3 | Implement a data structure that accomplishes: 4 | 5 | 1. Key/value pair insertion in O(1) time 6 | 2. Key/value pair removal in O(1) time 7 | 3. Key existence confirmation in O(1) time 8 | 4. Random key/value pair retrieval in O(1) time 9 | 10 | \[[Solution](solution.js)\] 11 | -------------------------------------------------------------------------------- /🚩 Bounce Back Stack/README.md: -------------------------------------------------------------------------------- 1 | ### BounceBackStack 2 | 3 | Contains two structures internally, a stack and a random access array/vector. Can perform push/pop/stackSize, and also insertFront/insertAt/insertBack/ totalSize/totalCapacity/randomAccessSize. Given an overall capacity, maintain this structure accordingly. 4 | 5 | \[[Solution](solution.cpp)\] 6 | -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Book Index Generator/README.md: -------------------------------------------------------------------------------- 1 | ### Book Index Generator 2 | 3 | Based on a book composed of words, generate an index of common words, followed by a listing of all the pages that they appear on. For simplicity, tokenize based on words, not phrases. 4 | 5 | Modification 1: How do you deal with unwanted/useless/common words? 6 | 7 | \[[Solution](solution.js)\] 8 | -------------------------------------------------------------------------------- /⭐ ⭐ Life Events/README.md: -------------------------------------------------------------------------------- 1 | ### Life Events 2 | 3 | Given a list of life events, where a life event is just a [birthYear, deathYear] tuple, find the number of people alive in a specific year. E.g., [[0,6], [12,19], [3,8], [2,5], [7,9]]. 4 | 5 | Modification 1: How do you find the max population size (and its year), such that it's not O(n^2)? 6 | 7 | \[[Solution](solution.js)\] 8 | -------------------------------------------------------------------------------- /⭐ Integer Set Duplicates/README.md: -------------------------------------------------------------------------------- 1 | ### Integer Set Duplicates 2 | 3 | Given an array of n+1 integers (each of which is selected from the set of numbers from 1 to n), write an algorithm that finds any duplicate. For example, you might be given arrays like so: [2, 3, 3, 1, 1], [4, 1, 3, 2, 4], and [2, 2, 2, 2, 2]. All of them select from the set {1, 2, 3, 4}. 4 | 5 | \[[Solution](solution.cpp)\] 6 | -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Palindrome Generator/README.md: -------------------------------------------------------------------------------- 1 | ### Palindrome Generator 2 | 3 | Print out all the 8-digit palindromes. Prefixed 0's do not count for valid palindromes. 4 | 5 | Modification 1: Generate all n-digit palindromes (where n can be even or odd). 6 | 7 | Modification 2: Generate all n-digit palindromes. String/array manipulation is not allowed. 8 | 9 | \[[Solution](solution.cpp)\] 10 | -------------------------------------------------------------------------------- /🚩 LRU Cache/README.md: -------------------------------------------------------------------------------- 1 | ### Least Recently Used (LRU) Cache 2 | 3 | Implement a least recently used (LRU) cache. This structure should provide the normal get value for key and set value for key functions. The cache has a capacity. Once you hit the capacity and try to add another key/value pair, then you remove key/value pair accessed the longest time ago. 4 | 5 | \[[Solution](solution.cpp)\] 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### Technical Interview Questions 2 | 3 | This repo contains a compilation of interview questions that I've either adapted from other people/resources or have created myself. The solutions (where they exist) are written in C++ or Javascript. Feel free to fork this repo and contribute more questions/solutions if you'd like. Navigate to each individual subdirectory to explore the question within. 4 | -------------------------------------------------------------------------------- /🚩 Process Invoker/README.md: -------------------------------------------------------------------------------- 1 | ### Process Invoker 2 | 3 | Assume that a Process consists of a process id (pid) and a list of pids representing invoked processes (child processes) by that Process. Given a list of Process objects and a specific pid, implement a function that returns all of the child processes by invoked that specific pid (recursively). 4 | 5 | // Tree, with traversal? Hashset? 6 | 7 | \[[Solution](solution.cpp)\] 8 | -------------------------------------------------------------------------------- /⭐ Balanced Binary Tree/README.md: -------------------------------------------------------------------------------- 1 | ### Balanced Binary Tree 2 | 3 | Implement a function that returns whether a given binary tree is balanced or not. 4 | 5 | An empty tree is considered height-balanced. A non-empty binary tree T is balanced if and only if 6 | T's left and right subtrees are both balanced, and the heights of T's left and right subtrees do 7 | not differ by more than 1. 8 | 9 | \[[Solution](solution.cpp)\] 10 | -------------------------------------------------------------------------------- /🚩 🚩 Server Farm Naming/README.md: -------------------------------------------------------------------------------- 1 | ### Server Farm Naming 2 | 3 | Assume that you're building a system of servers. You have a list of servers numbers (starting from the number "1") that represent the server names that have been taken. Find the earliest available name (lowest value number). 4 | 5 | Modification 1: Assume that there are different farms, i.e., amazon1, bloomberg1, amazon2, bloomberg3. How would you maintain this? 6 | 7 | \[[Solution](solution.cpp)\] 8 | -------------------------------------------------------------------------------- /⭐ Integer Set Duplicates/solution.cpp: -------------------------------------------------------------------------------- 1 | unsigned int anyDuplicate(vector numbers) { 2 | unordered_set numberExistence; 3 | for (int i = 0; i < numbers.size(); ++i) { 4 | unsigned int currentNumber = numbers[i]; 5 | if (numberExistence.contains(currentNumber)) { 6 | return currentNumber; 7 | } else { 8 | numberExistence.insert(currentNumber); 9 | } 10 | } 11 | throw -1; // Duplicates MUST exist 12 | } 13 | -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Random Linked List Deep Copy/README.md: -------------------------------------------------------------------------------- 1 | ### Random Node Linked List Deep Copy 2 | 3 | Assume you have a linked list, whose internal node contains data, a pointer to the next node, and a pointer to a random node somewhere in the linked list. Implement an algorithm that performs a deep copy of this linked list. 4 | 5 | ``` 6 | _________ ____ 7 | | ↓ ↓ | 8 | 1 -> 2 -> 3 -> 4 -> 5 -> X 9 | ↓ ⟳ ↓ 10 | X X 11 | 12 | 13 | ``` 14 | 15 | \[[Solution](solution.cpp)\] 16 | -------------------------------------------------------------------------------- /🚩 Linked List Common Ancestor/README.md: -------------------------------------------------------------------------------- 1 | ### Linked List Common Ancestors 2 | 3 | ![Linked List Common Ancestors Image](linked-list-common-ancestors.png) 4 | 5 | Given an arbitrary number of singly linked lists, return the earliest common ancestor node between all the linked lists. You are guaranteed that all of these linked lists converge, at the very least, at one tail node. Therefore, at worst, the result is the tail node. Otherwise, it is possible that all the lists converge earlier. 6 | 7 | \[[Solution](solution.cpp)\] 8 | -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Prefix Expression Evaluator/README.md: -------------------------------------------------------------------------------- 1 | ### Prefix Expression Evaluation 2 | 3 | Given a string containing a prefix expression, compute the value of the expression. For example: 4 | 5 | Prefix expression: 6 | `/ - 15 * / 3 2 5 5` 7 | (Result = 1.5) 8 | 9 | Relevant infix expression: 10 | `(15 - (3 / 2) * 5) / 5` 11 | 12 | You could also make this an infix or postfix evaluation problem, but you can just change the order 13 | of where an expression is evaluated via the stack. 14 | 15 | \[[Solution](solution.cpp)\] 16 | -------------------------------------------------------------------------------- /⭐ Min Stack/README.md: -------------------------------------------------------------------------------- 1 | ### Min Stack 2 | 3 | Use the [STL stack](http://www.cplusplus.com/reference/stack/stack/) and its provided functionality to find the minimum element in a stack. 4 | 5 | You may ONLY use stacks to complete this project (no other data structures, such as vectors or lists, are allowed). Moreover, the input stack MUST remain unchanged from its original state after the function returns; in other words, the stack has the same values in the same order after the function has completed. 6 | 7 | \[[Solution](solution.cpp)\] 8 | -------------------------------------------------------------------------------- /🚩 Minimum Maze Path/README.md: -------------------------------------------------------------------------------- 1 | ### Minimum Maze Path 2 | 3 | Given an m x n matrix of integers, starting from the upper left hand corner and moving only down or right, find the minimum possible value of a path to get to the bottom right hand corner. For example, 4 | 5 | |---|---|---|---|---| 6 | | 1 | 0 | 8 | 5 | 1 | 7 | |---|---|---|---|---| 8 | | 7 | 5 | 8 | 9 | 2 | 9 | |---|---|---|---|---| 10 | | 3 | 6 | 5 | 9 | 3 | 11 | |---|---|---|---|---| 12 | | 0 | 1 | 6 | 8 | 0 | 13 | |---|---|---|---|---| 14 | 15 | // Dynamic programming 16 | 17 | \[[Solution](solution.cpp)\] 18 | -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Skip List Validation/README.md: -------------------------------------------------------------------------------- 1 | ### Skip Linked List Validation 2 | 3 | Assume that you have a singly linked list that has nodes with an extra pointer called `skip`. Implement a function that validates that a given list is valid, given its head. 4 | 5 | ``` 6 | _________ ____ 7 | | ↓ | ↓ 8 | 1 -> 2 -> 3 -> 4 -> 5 -> X 9 | ↓ ↓ ↓ 10 | X X X 11 | ``` 12 | 13 | 1. `next` and `skip` form no loops. 14 | 2. `skip` always points forward in the linked list 15 | 3. `skip` always points to a node that exists in the list. 16 | 17 | 18 | \[[Solution](solution.cpp)\] 19 | -------------------------------------------------------------------------------- /⭐ Binary Tree String Builder/solution.cpp: -------------------------------------------------------------------------------- 1 | void leafPrint(Node* node) { 2 | leafPrintHelper(node, ""); 3 | } 4 | 5 | void leafPrintHelper(Node* node, const string& current) { 6 | string appendedString = current + node->data; 7 | if (node->isLeaf()) { 8 | cout << appendedString << endl; 9 | } else if (node->hasBothChildren()) { 10 | leafPrintHelper(node->left, appendedString); 11 | leafPrintHelper(node->right, appendedString); 12 | } else if (node->hasLeftChild()) { 13 | leafPrintHelper(node->left, appendedString); 14 | } else if (node->hasRightChild()) { 15 | leafPrintHelper(node->right, appendedString); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /🚩 🚩 InterconnectedServers/README.md: -------------------------------------------------------------------------------- 1 | ### Interconnected servers 2 | 3 | Given an interconnected cluster of computers, design a system where a single script can be deployed 4 | to a single origin machine that must then communicate (to itself and) to all of the other machines 5 | that that script needs to be executed. 6 | 7 | Modification 1: Multiple different scripts can be deployed to different origin machines and need to 8 | communicate execution. 9 | 10 | Modification 2: A single script might need to be run multiple times, but the instruction is given at 11 | different times and the same script might be deployed to different origin machines during each request. 12 | 13 | \[[Solution](solution.cpp)\] 14 | -------------------------------------------------------------------------------- /🚩 LRU Cache/solution.cpp: -------------------------------------------------------------------------------- 1 | // TODO: Keep a hash table of key/value pairs and also keep a priority queue (?) of key/timestamp pairs, 2 | // with the timestamp representing either when it was first added or when it was last accessed via get. 3 | class LRUCache { 4 | 5 | list lruList; 6 | unordered_map hashMap; 7 | unsigned int cacheSize; 8 | 9 | string get(string key) { 10 | list::iterator value = hashMap[key]; 11 | 12 | return value; 13 | } 14 | 15 | void set(string key, string value) { 16 | pq.push(make_pair(key, getDateTime())); 17 | data 18 | if (pq.size() > 10) { 19 | pq.pop(); 20 | } 21 | 22 | } 23 | 24 | } -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Skip List Validation/solution.cpp: -------------------------------------------------------------------------------- 1 | // O(n) 2 | // Handles skip pointing to itself, backwards, and outside of the lists 3 | // Also handles cycles, which is melded with skip checks for self and backwards 4 | bool validateSkipList(Node* head) { 5 | unordered_set seenNodes; 6 | 7 | Node* curr = head; 8 | while (curr) { 9 | seenNodes.add(curr); 10 | if (seenNodes.contains(curr->skip) || seenNodes.contains(curr->next)) { 11 | return false; 12 | } 13 | curr = curr->next; 14 | } 15 | 16 | curr = head; 17 | while (curr) { 18 | if (!seenNodes.contains(curr->skip)) { 19 | return false; 20 | } 21 | curr = curr->next; 22 | } 23 | 24 | return true; 25 | } -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Image Perimeter/README.md: -------------------------------------------------------------------------------- 1 | ### Image Perimeter 2 | 3 | Given a black and white image, represented as a multidimensional array of pixels where the color black is 0 and the color white is 1, and particular pixel coordinate, find the perimeter of the contiguous area occupied by the color at that pixel coordinate. 4 | 5 | ``` 6 | col ----> 7 | 8 | 0 1 2 3 4 9 | |---|-------|---|---| 10 | 0 | 0 | 1 1 | 0 | 1 | 11 | row | |---| | |---| 12 | | 1 | 0 0 | 1 | 0 0 | 13 | | | |---| |---| | 14 | \|/ 2 | 0 | 1 1 1 | 0 | 15 | | | |---| | | 16 | 3 | 0 | 1 | 0 | 1 | 0 | 17 | |---|---|---|---|---| 18 | ``` 19 | 20 | \[[Solution](solution.cpp)\] 21 | -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Wedding Appetizer Table/README.md: -------------------------------------------------------------------------------- 1 | ### Wedding Appetizer Table 2 | 3 | Imagine a party that has a table of appetizers containing individual plates of vegetable, shrimp, 4 | and beef appetizers. The server behind the table has an interest in giving the oldest dish available 5 | at that table, so as to prevent food poisoning by keeping a dish around longer than it needs to be. 6 | The server can replenish the stock of each appetizer, one dish at a time. A guest can come up to the 7 | table and request one specific appetizer. However, a guest might also not care what he/she receives, 8 | and can therefore request that the server choose the dish themselves. Design and implement a system 9 | that satisfies all of these needs. 10 | 11 | \[[Solution](solution.cpp)\] 12 | -------------------------------------------------------------------------------- /⭐ ⭐ Multi-Stock Sorter/README.md: -------------------------------------------------------------------------------- 1 | ### Stocks Ultra Sorter 2 | 3 | Given several sorted lists of stock prices, return a combined sorted list of all of the stock prices. 4 | 5 | ``` 6 | Input: 7 | { 8 | "MSFT": [54, 56, 89, 100], 9 | "GOOG": [33, 54, 55, 90], 10 | "AAPL": [33, 36, 60, 90, 100], 11 | "META": [56, 75, 89, 112], 12 | } 13 | 14 | Result: 15 | [ 16 | (33,"GOOG"), 17 | (33,"AAPL"), 18 | (36,"AAPL"), 19 | (54,"MSFT"), 20 | (54,"GOOG"), 21 | (55,"GOOG"), 22 | (56,"META"), 23 | (56,"MSFT"), 24 | (60,"AAPL"), 25 | (75,"META"), 26 | (89,"MSFT"), 27 | (89,"META"), 28 | (90,"AAPL"), 29 | (90,"GOOG"), 30 | (100,"AAPL"), 31 | (100,"MSFT"), 32 | (112,"META"), 33 | ] 34 | ``` 35 | 36 | Modification 1: Solution cannot use any external sorting tools or be O(n log n). 37 | 38 | \[[Solution](solution.cpp)\] 39 | -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Image Paint Bucket Tool/README.md: -------------------------------------------------------------------------------- 1 | ### Paint Bucket Tool 2 | 3 | Assume that you have an image composed of RGB colors. You need to implement the paint bucket tool, whereby you select a target pixel and a specific color, and fill in all the contiguous pixels colored the same way as the target pixel. 4 | 5 | ``` 6 | col ----> 7 | 8 | 0 1 2 3 4 9 | |---|-------|---|---| 10 | 0 | 0 | 3 | 0 | 2 | 4 | 11 | row | |---| | |---| 12 | | 1 | 0 0 0 | 2 2 | 13 | | | |---|---| | 14 | \|/ 2 | 0 | 1 1 | 2 2 | 15 | | | |---|---| | 16 | 3 | 0 | 1 | 0 | 1 | 2 | 17 | |---|---|---|---|---| 18 | 19 | Assuming (row, col) format and 0-based indexes, pixel (3, 1) contains the color 1. 20 | ``` 21 | 22 | \[[Solution](solution.cpp)\] 23 | -------------------------------------------------------------------------------- /⭐ ⭐ Course Prerequisites/README.md: -------------------------------------------------------------------------------- 1 | ### Course Prerequisites 2 | 3 | Assume that you are the head of the Computer Science Department at your university. You know all the courses that your program offers--you know what skills are needed in advance of each course and you know what skills each course teaches. Given a specific course, determine which prerequisites you need. To start, do this in such a way that makes it simpler for the administration, by making it quicker to figure out. 4 | 5 | Example: 6 | 7 | CS1 8 | Needs: None 9 | Teaches: A, B 10 | 11 | CS2 12 | Needs: None 13 | Teaches: B, C 14 | 15 | CS3 16 | Needs: None 17 | Teaches: B, D 18 | 19 | CS4 20 | Needs: None 21 | Teaches: C 22 | 23 | CS5 24 | Needs: A, B, C 25 | Teaches: D, E 26 | 27 | CS10 28 | Needs: A, D 29 | Teaches: F, G 30 | 31 | CS50 32 | Needs: B, C, D, E 33 | Teaches: H, I 34 | 35 | Modification 1: How would you optimize for students? 36 | 37 | \[[Solution](solution.js)\] 38 | -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Palindrome Generator/solution.cpp: -------------------------------------------------------------------------------- 1 | void printValidPalindromes(unsigned int numberOfDigits) { 2 | bool isEven = numberOfDigits % 2 == 0; 3 | unsigned int halfNumberOfPlaces = numberOfDigits / 2; 4 | unsigned long long minLeftNumber = pow(10, halfNumberOfPlaces - 1); 5 | unsigned long long maxLeftNumber = minLeftNumber * 10 - 1; 6 | 7 | unsigned long long currentLeftTemp; 8 | unsigned long long currentRight = 0; 9 | for(int currentLeft = minLeftNumber; currentLeft <= maxLeftNumber; currentLeft++) { 10 | currentLeftTemp = currentLeft; 11 | while (currentLeftTemp > 0) { 12 | currentRight = currentRight * 10 + currentLeftTemp % 10; 13 | currentLeftTemp /= 10; 14 | } 15 | if (isEven) { 16 | cout << currentLeft * pow(10, halfNumberPlaces) + currentRight << endl; 17 | } else { 18 | for (int i = 0; i < 10; ++i) { 19 | cout << (currentLeft * 10 + i) * pow(10, halfNumberPlaces) + currentRight << endl; 20 | } 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /⭐ ⭐ Random Hash Table/solution.js: -------------------------------------------------------------------------------- 1 | class InstaRandom { 2 | constructor() { 3 | this.map = {}; 4 | this.indexMap = {}; 5 | this.array = []; 6 | } 7 | 8 | insert(key, value) { 9 | this.map[key] = value; 10 | this.array.push(key); 11 | this.indexMap[key] = this.array.size() - 1; 12 | } 13 | 14 | remove(key) { 15 | this.map[key] = undefined; 16 | for (let i = 0; i < this.array.size(); i++) { 17 | if (this.array[i] === key) { 18 | this.array[i] = this.array[this.array.size() - 1]; 19 | this.array.popBack(); 20 | } 21 | } 22 | } 23 | 24 | contains(key) { 25 | return this.map[key] != null; 26 | } 27 | 28 | getRandom() { 29 | let result = { key: null, value: null }; 30 | const randomIndex = getRandomInt(0, this.array.size() - 1); 31 | result.key = this.array[randomIndex]; 32 | result.value = this.map[result.key]; 33 | return result; 34 | } 35 | } -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Book Index Generator/solution.js: -------------------------------------------------------------------------------- 1 | type Book = Page[]; 2 | type Page = Word[]; 3 | type Word = string; 4 | 5 | // O(p * w), where p is the number of pages and w is the average number of words per page 6 | // Return an (ordered) map, mapping words to vector of integers, representing pages. 7 | // Pitfall 1: The same word can exist multiple times on a page. 8 | function generateIndex(book: Book, unimportantWords: Set) { 9 | const index = new OrderedMap(string, int[]); 10 | for (let pageNumber = 0; pageNumber < book.size(); pageNumber++) { 11 | const page = book[pageNumber]; 12 | for (let word in page) { 13 | if (unimportantWords.contains(words)) { 14 | continue; 15 | } 16 | 17 | if (index[word] && index[word].back() === pageNumber) { 18 | continue; 19 | } else if (!index[word]) { 20 | index[word] = [] 21 | } 22 | index[word].push(pageNumber); 23 | } 24 | } 25 | return index; 26 | } -------------------------------------------------------------------------------- /⭐ Min Stack/solution.cpp: -------------------------------------------------------------------------------- 1 | // Remember that top() gets you (reference to) the value at the top of the stack 2 | // and that pop() actually takes the element off of the top (but returns nothing) 3 | int getMinimumElementInStack(stack& inputStack) 4 | { 5 | // Temporary stack that will hold the integers in 6 | // inputStack except "upside-down" as we pop off 7 | stack x; 8 | 9 | // Start off our minimum element with the value at the top of the stack 10 | int min = inputStack.top(); 11 | 12 | // Cycle through all of the values in the stack by popping them 13 | // off of inputStack and placing them in a different stack (x) 14 | // If we find a smaller element than min, save its value in min 15 | while( !inputStack.empty() ) 16 | { 17 | x.push(inputStack.top()); 18 | if(inputStack.top() < min) 19 | { 20 | min = inputStack.top(); 21 | } 22 | inputStack.pop(); 23 | } 24 | 25 | // Be sure to return inputStack back to its initial state 26 | while( !x.empty() ) 27 | { 28 | inputStack.push(x.top()); 29 | x.pop(); 30 | } 31 | 32 | return min; 33 | } 34 | -------------------------------------------------------------------------------- /⭐ ⭐ Course Prerequisites/solution.js: -------------------------------------------------------------------------------- 1 | type Course = { 2 | courseId: String, 3 | skillsNeeded: String[], 4 | skillsTaught: String[], 5 | } 6 | 7 | 8 | class CSCurriculum { 9 | constructor() { 10 | this.courses = {}; 11 | this.skillsTree = {}; 12 | } 13 | 14 | buildSkillTree() { 15 | this.skillsTree = {} 16 | for (let course in courses) { 17 | const { courseId, skillsTaught } = course; 18 | for (let skill in skillsTaught) { 19 | this.skillTree[skill].push(courseId); 20 | } 21 | } 22 | } 23 | 24 | // Simpler for administration, but could be more cumbersome for students 25 | getSimplestPrerequisites(course) { 26 | const prerequisites = []; 27 | const { skillsNeeded } = course; 28 | for (let skill in skillsNeeded) { 29 | const simplestCourse = this.skillTree[skill].top(); 30 | prerequisites.push(simplestCourse) 31 | } 32 | return prerequisites; 33 | } 34 | 35 | // Less onerous for students, but could take more thinking from the administration 36 | getLeastCoursesPrerequisites(course) { 37 | // TODO 38 | } 39 | } -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Image Paint Bucket Tool/solution.cpp: -------------------------------------------------------------------------------- 1 | bool paintBucket(vector>& image, unsigned int row, unsigned int col, targetColor) { 2 | if (isInBounds(image, row, col)) { 3 | return; 4 | } 5 | 6 | unsigned int startColor = image[row][col]; 7 | paintBucketHelper(image, row, col, startColor, targetColor); 8 | } 9 | 10 | void paintBucketHelper( 11 | vector>& image, 12 | unsigned int currentRow, 13 | unsigned int currentColumn, 14 | unsigned int startColor, 15 | unsigned int targetColor 16 | ) { 17 | if (!isInBounds(image, currentRow, currentColumn) || image[currentRow][currentColumn] != startColor) { 18 | return; 19 | } 20 | image[currentRow][currentColumn] = targetColor; 21 | paintBucketHelper(image, currentRow-1, currentColumn, startColor, targetColor); // Up 22 | paintBucketHelper(image, currentRow+1, currentColumn, startColor, targetColor); // Down 23 | paintBucketHelper(image, currentRow, currentColumn-1, startColor, targetColor); // Left 24 | paintBucketHelper(image, currentRow, currentColumn+1, startColor, targetColor); // Right 25 | } 26 | 27 | 28 | bool isInBounds(const vector>& image, unsigned int row, unsigned int col) { 29 | return image.size() <= row || image[0].size() <= col || row == 0 || col == 0 30 | } 31 | -------------------------------------------------------------------------------- /⭐ ⭐ Exam Preparedness/README.md: -------------------------------------------------------------------------------- 1 | ### Exam Preparedness 2 | 3 | In order for a student to be considered as understanding a set of material in a textbook, they need to at least have read it X times. 4 | 5 | Given the required pages (assumed to be pages 1 through `pagesAssigned`), the number of times a single page must be read to be understood (an integer `numberOfTimesToRead`), and a finite stream of how the student read the pages (an array of page numbers, `pagesRead`), determine whether the student understands the material required for the exam. 6 | 7 | Note that the pages read by the student could be out of order, not necessarily required for the exam, and could exceed the number of times necessary for a single page. An example stream is passed in like so: 8 | 9 | [1,2,3,4,1,3,4,1,2,3,4,5,6,7,8,3,4,5,6,7] 10 | 11 | Modification 1: The required pages could be several ranges of contiguous pages. In other words, instead of being a vector of required pages, the function is passed a sorted array of tuples, with each tuple representing a start/end page range and all the tuples in totality representing ALL of the required pages. 12 | 13 | Modification 2: How would we deal with this if the pages read are not a finite stream, but rather, occur in ticks, i.e., every time a page is read, a pageRead function is called. 14 | 15 | \[[Solution](solution.cpp)\] 16 | -------------------------------------------------------------------------------- /⭐ ⭐ Exam Preparedness/solution.cpp: -------------------------------------------------------------------------------- 1 | // numberOfPages: Reading from page 1 to numberOfPages 2 | // numberOfTimesNecessaryToRead: Assumed to be a minimum of 1 3 | // pagesRead: Contains only the pages necessary to read 4 | bool understandsExamMaterial(int numberOfPages, 5 | int numberOfTimesNecessaryToRead, 6 | vector pagesRead) { 7 | if (pagesRead.size() < numberOfTimesNecessaryToRead * numberOfPages) 8 | return false; 9 | 10 | // mapping page numbers to number of times read 11 | unordered_map pagesReadCounters; 12 | 13 | for (int i = 0; i < pagesRead.size(); ++i) { 14 | int currentPage = pagesRead[i]; 15 | if (pagesReadCounters.count(currentPage) == 0) { 16 | pagesReadCounters[currentPage] = 1; 17 | } else { 18 | pagesReadCounters[currentPage]++; 19 | } 20 | } 21 | 22 | if (pagesReadCounters.size() < numberOfPages) { 23 | return false; 24 | } 25 | 26 | if (numberOfTimesNecessaryToRead == 1) { 27 | return true; 28 | } 29 | 30 | for (auto page: pagesReadCounters) { 31 | int numberOfTimesCurrentPageHasBeenRead = pagesReadCounters[page]; 32 | if (numberOfTimesCurrentPageHasBeenRead < numberOfTimesNecessaryToRead) 33 | return false; 34 | } 35 | 36 | return true; 37 | } 38 | 39 | // TODO: Solution for modification 1 40 | -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Prefix Expression Evaluator/solution.cpp: -------------------------------------------------------------------------------- 1 | // Solution: Use a stack to get one element at a time (numbers could be multiple characters so 2 | // assume that it's whitespace separated. When you come upon an operation, push it onto the stack. 3 | // When you come upon a first number, push it onto the stack. When you come upon a second number, 4 | // pop the top number off and pop the operation off, and perform the operation on the second number 5 | // and the popped off (first) number. 6 | double Evaluate(vector &input) { 7 | vector result; 8 | 9 | for(int i = input.size() - 1;i >= 0; i--) 10 | { 11 | if(!IsOperator(input[i])) 12 | { 13 | result.push_back(stoi(input[i])); 14 | } 15 | else 16 | { 17 | Assert(result.size() >= 2); 18 | 19 | double op1 = result.back(); 20 | result.pop_back(); 21 | 22 | double op2 = result.back(); 23 | result.pop_back(); 24 | 25 | double answer = PerformOperation(op1, op2, input[i]); 26 | result.push_back(answer); 27 | } 28 | } 29 | 30 | Assert(result.size() == 1); 31 | return result.back(); 32 | } 33 | 34 | double PerformOperation(double op1, double op2, string oper) { 35 | switch(op) 36 | { 37 | op1 oper op2 38 | 39 | case "/" 40 | op == 0 41 | throw divideByzero 42 | } 43 | } 44 | 45 | bool IsOperator(string op) { 46 | return (op == "+" || op == "-" || op == "*" || op == "/"); 47 | } 48 | -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Wedding Appetizer Table/solution.cpp: -------------------------------------------------------------------------------- 1 | struct Appetizer { 2 | string type; 3 | time_t creationTime; 4 | }; 5 | 6 | class AppetizerTable { 7 | private: 8 | 9 | vector> appetizerQueues; 10 | unordered_map appetizerQueueIndices; 11 | 12 | public: 13 | 14 | void replenishAppetizer(const string& type) 15 | { 16 | Appetizer* appetizer = new Appetizer(type, getCurrentTime()); 17 | int appetizerQueueIndex = appetizerQueueIndices[type]; 18 | appetizerQueues[appetizerQueueIndex].push(appetizer); 19 | } 20 | 21 | Appetizer* serveAppetizer(const string& type) 22 | { 23 | int appetizerQueueIndex = appetizerQueueIndices[type]; 24 | Appetizer* appetizer = appetizerQueues[appetizerQueueIndex].top(); 25 | appetizerQueues[appetizerQueueIndex].pop(); 26 | return appetizer; 27 | } 28 | 29 | Appetizer* serveAnyAppetizer() 30 | { 31 | int oldestAppetizerIndex = 0; 32 | Appetizer* currentOldestAppetizer; 33 | Appetizer* currentAppetizer; 34 | for (int i = 1; i < appetizerQueues.size(); ++i) 35 | { 36 | currentOldestAppetizer = appetizerQueues[oldestAppetizerIndex].top(); 37 | currentAppetizer = appetizerQueues[i].top(); 38 | if (currentOldestAppetizer.creationTime > currentAppetizer.creationTime) 39 | { 40 | oldestAppetizerIndex = i; 41 | } 42 | } 43 | Appetizer* appetizer = appetizerQueues[appetizerQueueIndex].top(); 44 | appetizerQueues[appetizerQueueIndex].pop(); 45 | return appetizer; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Image Perimeter/solution.cpp: -------------------------------------------------------------------------------- 1 | unsigned int getPerimeter(const vector>& image, unsigned int row, unsigned int col) { 2 | if (image.size() <= row || image[0].size() <= col || row == 0 || col == 0) { 3 | return 0; 4 | } 5 | 6 | vector> visited; 7 | fillWithFalse(visited); 8 | 9 | unsigned int runningPerimeter = 0; 10 | unsigned int startColor = image[row][col]; 11 | perimeterHelper(image, visited, row, col, runningPerimeter, startColor); 12 | 13 | return perimeter; 14 | } 15 | 16 | void perimeterHelper( 17 | const vector>& image, 18 | const vector>& visited, 19 | unsigned int currentRow, 20 | unsigned int currentColumn, 21 | unsigned int& runningPerimeter, 22 | unsigned int startColor 23 | ) { 24 | 25 | if (!isInBounds(image, currentRow, currentColumn)) { 26 | return; 27 | } 28 | 29 | bool didVisit = visited[currentRow][currentColumn]; 30 | const currentColor = image[currentRow][currentColumn]; 31 | if (didVisit || currentColor != startColor) { 32 | return; 33 | } 34 | 35 | // Reaching this point means current pixel is same color as start pixel 36 | 37 | visited[currentRow][currentColumn] = true; 38 | 39 | if (!isInBounds(image, currentRow+1, currentColumn) || 40 | image[currentRow+1][currentColumn] != startColor) { 41 | runningPerimeter += 1; 42 | } 43 | // Repeat for the other three 44 | 45 | perimeterHelper(image, visited, currentRow+1, currentColumn, runningPerimeter, startColor); 46 | // Repeat for the other three 47 | } 48 | 49 | bool isInBounds(const vector>& image, unsigned int row, unsigned int col) { 50 | return image.size() <= row || image[0].size() <= col || row == 0 || col == 0 51 | } 52 | -------------------------------------------------------------------------------- /⭐ ⭐ ⭐ Random Linked List Deep Copy/solution.cpp: -------------------------------------------------------------------------------- 1 | // Solution 1 2 | // Create intermediary nodes between each node such that the intermediary nodes 3 | // build up to the new list. (Note that this modifies the original list) 4 | 5 | RandomListNode* copyRandomListNode(RandomListNode* head){ 6 | // 1st round, create new nodes in O(n) 7 | RandomListNode* current = head; 8 | while (current != NULL) { 9 | RandomListNode* newCurrent = new RandomListNode(current->value); 10 | RandomListNode* next = current->next; 11 | current->next = newCurrent; 12 | newCurrent->next = next; 13 | current = next; 14 | } 15 | 16 | // 2nd round, copy random pointer 17 | current = head; 18 | while (current != NULL && current->next != NULL) { 19 | current->next->random = current->random->next; // Think about it! 20 | current = current->next->next; // Iterate twice to get to next "old" node 21 | } 22 | 23 | // 3rd round, extract new list 24 | current = head; 25 | RandomListNode* newHead = NULL; 26 | while (current != NULL) { 27 | RandomListNode* newCurrent = current->next; 28 | current->next = newCurrent->next; 29 | newCurrent->next = current->next; 30 | if (newHead == NULL) { 31 | newHead = newCurrent; 32 | } 33 | if (current->next == NULL) { 34 | break; 35 | } 36 | current = current->next; 37 | } 38 | return newHead; 39 | } 40 | 41 | // TODO: Solution 2 42 | // Use a hash table to map old nodes to new nodes. Iterate through the linked list, 43 | // creating new nodes as you go, linked to the correct next node, and updating the 44 | // hash table with the correct new node values. Then, perform a second iteration 45 | // whereby you populate the random pointer based on the values in the hash table. 46 | -------------------------------------------------------------------------------- /⭐ ⭐ Life Events/solution.js: -------------------------------------------------------------------------------- 1 | // O(n), where n is the number of life events 2 | // If unsorted, iterate over the life events array. 3 | // If you see a birth year value less than or equal to the target year, increment a counter of people alive up until that year. 4 | // If you see a death year value less than or equal to the target year, decrement the counter of people alive up until that year. 5 | // If sorted, you can do an early stop once the birth year value exceeds the target year. 6 | function findPopulationSize(lifeEvents, year) { 7 | const populationSize = 0; 8 | for (let lifeEvent in lifeEvents) { 9 | const { birthYear, deathYear } = lifeEvent; 10 | if (birthYear <= year) { 11 | populationSize++; 12 | } 13 | if (deathYear <= year) { 14 | populationSize--; 15 | } 16 | } 17 | return populationSize; 18 | } 19 | 20 | // Modification 1 21 | // O(n * k) time, O(k) space, where k is the full possible range of years 22 | function findMaxPopulationSize(lifeEvents) { 23 | const populationPerYear = {}; 24 | for (let lifeEvent in lifeEvents) { 25 | const { birthYear, deathYear } = lifeEvent; 26 | for (const year = birthYear; year <= deathYear; year++) { 27 | if (!populationPerYear[birthYear]) { 28 | populationPerYear[birthYear] = 1; 29 | } else { 30 | populationPerYear[birthYear]++; 31 | } 32 | } 33 | } 34 | 35 | const maxPopulation = { size: 0, year: 0 }; 36 | for (let year of populationPerYear) { 37 | const currentPopulationSize = populationPerYear[year]; 38 | if (maxPopulation.size < currentPopulationSize) { 39 | maxPopulation.size = currentPopulationSize; 40 | maxPopulation.year = year; 41 | } 42 | } 43 | 44 | return maxPopulation; 45 | } 46 | 47 | 0, 10 48 | 0, 12 49 | 0, 15 -------------------------------------------------------------------------------- /⭐ Balanced Binary Tree/solution.cpp: -------------------------------------------------------------------------------- 1 | // This implementation of a binary tree does NOT use "nodes" (and therefore has no "root" pointer) 2 | // Instead, the Tree itself contains data, and holds pointers to its children (other Trees) 3 | template 4 | class Tree { 5 | private: 6 | Tree* left; 7 | Tree* right; 8 | ItemType data; 9 | 10 | public: 11 | Tree(ItemType _data) : left(NULL), right(NULL), data(_data) {} 12 | 13 | bool isBalanced() 14 | { 15 | // Base case when the current tree is a leaf (no children) 16 | if(left == NULL && right == NULL) 17 | { 18 | return true; 19 | } 20 | 21 | // Case when the current tree only has one child 22 | // Note that, in order for this current tree to be balanced, if one 23 | // child is NULL, then the other child must be a leaf (aka, 0 height) 24 | else if(left == NULL && right != NULL) 25 | { 26 | return right->height() == 0; 27 | } 28 | else if(right == NULL && left != NULL) 29 | { 30 | return left->height() == 0; 31 | } 32 | 33 | // Case when the current tree has both children 34 | else 35 | { 36 | bool bothChildrenAreBalanced = left->isBalanced() && right->isBalanced(); 37 | bool differenceInChildrensHeightDoesNotExceed1 = abs(left->height() - right->height()) <= 1; 38 | return bothChildrenAreBalanced && differenceInChildrenHeightDoesNotExceed1; // this logically flows from the definition! 39 | } 40 | } 41 | 42 | // It was necessary to write the height function because the definition 43 | // of a balanced tree requires knowing the height (of its children) 44 | int height() 45 | { 46 | // Base case; the current tree is a leaf node (no children) 47 | // By definition, the height of a leaf node is 0. 48 | if(left == NULL && right == NULL) 49 | { 50 | return 0; 51 | } 52 | 53 | // Cases when the current tree has only one child 54 | // Only necessary to recurse downward in one direction 55 | else if(left == NULL && right != NULL) 56 | { 57 | return 1 + right->height(); 58 | } 59 | else if(right == NULL && left != NULL) 60 | { 61 | return 1 + left->height(); 62 | } 63 | 64 | // Case when the current tree has both children 65 | // Necessary to find the maximum between your children's heights 66 | else 67 | { 68 | return 1 + max(right->height(), left->height()); 69 | } 70 | } 71 | }; 72 | -------------------------------------------------------------------------------- /⭐ ⭐ Multi-Stock Sorter/solution.cpp: -------------------------------------------------------------------------------- 1 | // Less efficient way that is O(m^2 * n), where m is the number of lists and n is 2 | // the average number of elements in each list. 3 | void ultraSort(const vector>& stockPrices) { 4 | vector finalSortedVector; 5 | vector currentVectorIndices(stockPrices.size()); // Assume they start with 0 6 | vector currentActiveVectors(stockPrices.size()); 7 | for (int i = 0; i < stockPrices.size(); ++i) { 8 | currentActiveVectors.push_back(i); 9 | } 10 | 11 | unsigned int currentActiveVectorIndex; 12 | unsigned int currentActiveVectorMinIndex; 13 | unsigned int currentIndexWithinActiveVector; 14 | unsigned int currentMinIndexWithinActiveVector; 15 | double currentStockPrice; 16 | double currentMinStockPrice = DOUBLE_MAX; 17 | 18 | while (numberOfActiveVectorsLeft) { 19 | for(int i = 0; i < currentActiveVectors.size(); ++i) { 20 | currentActiveVectorIndex = currentActiveVectors[i]; 21 | currentIndexWithinActiveVector = currentVectorIndices[currentActiveVectorIndex]; 22 | currentStockPrice = stockPrices[i][currentIndex]; 23 | if (currentStockPrice < currentMinStockPrice) { 24 | currentActiveVectorMinIndex = currentActiveVectorIndex; 25 | currentMinStockPrice = currentStockPrice; 26 | } 27 | currentMinIndexWithinActiveVector = currentVectorIndices[currentActiveVectorMinIndex]; 28 | } 29 | } 30 | } 31 | 32 | // More efficient solution that is O(m * n * log m) determines max using a priority queue 33 | void ultraSort(const list>& stockPrices) { 34 | priority_queue> priorityQ(sortByStockPriceInPair); // assume exists 35 | vector finalSortedVector; 36 | 37 | // Initialization step 38 | for (int i = 0; i < stockPrices.size(); ++i) { 39 | vector& currentStockPricesList = stockPrices[i]; 40 | pair startEntry = create_pair(i, currentStockPricesList.front()); 41 | priorityQ.push(startEntry); 42 | } 43 | 44 | // O(m * n) 45 | while (!priorityQ.empty()) { 46 | pair currentEntry = priorityQ.pop(); 47 | int vectorIndex = currentEntry.getFirst(); 48 | double stockPrice = currentEntry.getSecond(); 49 | vector& currentStockPricesList = stockPrices[vectorIndex]; 50 | currentStockPricesList.popFront(); 51 | finalSortedVector.push(stockPrice); 52 | 53 | // O(log m) 54 | if (!currentStockPricesList.empty()) { 55 | double nextValue = currentStockPricesList.top(); 56 | pair nextEntry = create_pair(vectorIndex, nextValue); 57 | } 58 | } 59 | 60 | return finalSortedVector; 61 | } -------------------------------------------------------------------------------- /⭐ Binary Search Tree Generator/solution.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | using namespace std; 5 | 6 | // This implementation of a binary tree DOES use 7 | // "nodes" (and therefore has a "root" pointer) 8 | template 9 | class Tree { 10 | public: 11 | void createTree(const vector& sortedVec); 12 | private: 13 | 14 | struct TreeNode 15 | { 16 | T data; 17 | TreeNode* right; 18 | TreeNode* left; 19 | }; 20 | 21 | TreeNode* root; 22 | 23 | void createTree(TreeNode*& treeNode, const vector& sortedVec, int start, int end); 24 | 25 | /* Other possible implementation that returns "updated" tree! 26 | Note the new return type (TreeNode*) and changed first parameter (no &) 27 | 28 | TreeNode* createTree(TreeNode* treeNode, const vector& sortedVec, int start, int end); 29 | 30 | */ 31 | 32 | }; 33 | 34 | template 35 | void Tree::createTree(const vector& sortedVec) 36 | { 37 | // Shortcut case; if the tree has data, abort the operation 38 | // The tree must be empty in order to be generated with a sorted vector 39 | if(root != NULL) { 40 | return; 41 | } 42 | 43 | // Kick off the initial call to the recursive helper 44 | createTree(root, sortedVec, 0, sortedVec.size()-1); 45 | 46 | /* Code using other implementation of createTree() 47 | 48 | root = createTree(root, sortedVector, 0, sortedVec.size()-1); 49 | 50 | */ 51 | } 52 | 53 | template 54 | void Tree::createTree(TreeNode*& treeNode, const vector& sortedVec, int start, int end) 55 | { 56 | // Base case when the start and end have crossed (because of mid +/- 1 in the recursive calls) 57 | if(end < start) { 58 | return; 59 | } 60 | 61 | int mid = (end + start) / 2; 62 | 63 | treeNode = new TreeNode; 64 | treeNode->data = sortedVec[mid]; 65 | 66 | createTree(treeNode->left, sortedVec, start, mid - 1); 67 | createTree(treeNode->right, sortedVec, mid + 1, end); 68 | } 69 | 70 | /* 71 | Other possible implementation of createTree that returns "updated tree" 72 | 73 | template 74 | TreeNode* Tree::createTree(TreeNode* treeNode, const vector& sortedVec, int start, int end) 75 | { 76 | // Base case when the start and end have crossed (because of mid +/- 1 in the recursive calls) 77 | if(end < start) 78 | { 79 | return NULL; 80 | } 81 | 82 | else 83 | { 84 | int mid = (end + start) / 2; 85 | 86 | treeNode = new TreeNode; 87 | treeNode->data = sortedVec[mid]; 88 | 89 | treeNode->left = createTree(treeNode->left, sortedVec, start, mid - 1); 90 | treeNode->right = createTree(treeNode->right, sortedVec, mid + 1, end);\ 91 | 92 | return treeNode; 93 | } 94 | } 95 | */ 96 | --------------------------------------------------------------------------------