Meta Interview Problems

Ace your homework & exams now with Quizwiz!

Quick Select

Quickselect is an algorithm to find the k-th smallest element in an unordered list. It's similar to the QuickSort algorithm and was developed by Tony Hoare. Here's a brief explanation: 1. **Choose a Pivot:** Select an element from the array as the pivot. 2. **Partition:** Rearrange the array so that all elements less than the pivot come before it and all greater elements come after it. The pivot is now in its final position. 3. **Select:** - If the pivot's position is k, return the pivot. - If the pivot's position is greater than k, repeat the process on the left subarray. - If the pivot's position is less than k, repeat on the right subarray. Quickselect typically has an average-case time complexity of O(n) but can be O(n²) in the worst case. Unlike QuickSort, it doesn't sort the entire list but only partitions enough to find the k-th smallest element.

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. Example 1: Input: s = "leetcode", wordDict = ["leet","code"] Output: true Explanation: Return true because "leetcode" can be segmented as "leet code". Example 2: Input: s = "applepenapple", wordDict = ["apple","pen"] Output: true Explanation: Return true because "applepenapple" can be segmented as "apple pen apple". Note that you are allowed to reuse a dictionary word. Example 3: Input: s = "catsandog", wordDict = ["cats","dog","sand","and","cat"] Output: false

- Build a trie from wordDict. Each node should also have an isWord attribute. Store the root of the trie in root. - Initialize an array dp with the same length as s and all values initially set to false. - Iterate i over the indices of s. At each i:Check if i == 0 or dp[i - 1] = true. If not, continue to the next i.Set curr = root. Iterate j over the indices of s, starting from i. At each j,Get the character at index j as c = s[j].If c is not in the children of curr, we can break from the loop.Otherwise, move curr to the child labeled c.If curr.isWord, set dp[j] = true. - Return dp[s.length - 1]. class Solution { wordBreak(s, wordDict) { const root = new TrieNode(); // Build Trie for (const word of wordDict) { let curr = root; for (const c of word) { if (!curr.children[c]) { curr.children[c] = new TrieNode(); } curr = curr.children[c]; } curr.isWord = true; } const dp = new Array(s.length).fill(false); for (let i = 0; i < s.length; i++) { if (i === 0 || dp[i - 1]) { let curr = root; for (let j = i; j < s.length; j++) { const c = s[j]; if (!curr.children[c]) { break; } curr = curr.children[c]; if (curr.isWord) { dp[j] = true; } } } } return dp[s.length - 1]; } } // Example usage const solution = new Solution(); const s = "leetcode"; const wordDict = ["leet", "code"]; console.log(solution.wordBreak(s, wordDict)); // Output: true https://leetcode.com/problems/word-break/description/

Given a string s which represents an expression, evaluate this expression and return its value. The integer division should truncate toward zero. You may assume that the given expression is always valid. All intermediate results will be in the range of [-231, 231 - 1]. Note: You are not allowed to use any built-in function which evaluates strings as mathematical expressions, such as eval(). Example 1: Input: s = "3+2*2" Output: 7 Example 2: Input: s = " 3/2 " Output: 1 Example 3: Input: s = " 3+5 / 2 " Output: 5

- Instead of using a stack, we use a variable lastNumber to track the value of the last evaluated expression. - If the operation is Addition (+) or Subtraction (-), add the lastNumber to the result instead of pushing it to the stack. The currentNumber would be updated to lastNumber for the next iteration. - If the operation is Multiplication (*) or Division (/), we must evaluate the expression lastNumber X currentNumber and update the lastNumber with the result of the expression. This would be added to the result after the entire string is scanned. ```js var calculate = function(s) { if (s === null || s.length === 0) return 0; let length = s.length; let currentNumber = 0, lastNumber = 0, result = 0; let operation = '+'; for (let i = 0; i < length; i++) { let currentChar = s[i]; if (!isNaN(parseInt(currentChar))) { currentNumber = (currentNumber * 10) + (parseInt(currentChar)); } if (isNaN(parseInt(currentChar)) && currentChar !== ' ' || i === length - 1) { if (operation === '+' || operation === '-') { result += lastNumber; lastNumber = (operation === '+') ? currentNumber : -currentNumber; } else if (operation === '*') { lastNumber = lastNumber * currentNumber; } else if (operation === '/') { lastNumber = Math.trunc(lastNumber / currentNumber); } operation = currentChar; currentNumber = 0; } } result += lastNumber; return result; }; ``` Time: O(n) Space: O(1) https://leetcode.com/problems/basic-calculator-ii/

Given two sparse vectors, compute their dot product. Implement class SparseVector: SparseVector(nums) Initializes the object with the vector nums dotProduct(vec) Compute the dot product between the instance of SparseVector and vec A sparse vector is a vector that has mostly zero values, you should store the sparse vector efficiently and compute the dot product between two SparseVector. Follow up: What if only one of the vectors is sparse? Example 1: Input: nums1 = [1,0,0,2,3], nums2 = [0,3,0,4,0] Output: 8 Explanation: v1 = SparseVector(nums1) , v2 = SparseVector(nums2) v1.dotProduct(v2) = 1*0 + 0*3 + 0*0 + 2*4 + 3*0 = 8 Example 2: Input: nums1 = [0,1,0,0,0], nums2 = [0,0,0,0,2] Output: 0 Explanation: v1 = SparseVector(nums1) , v2 = SparseVector(nums2) v1.dotProduct(v2) = 0*0 + 1*0 + 0*0 + 0*0 + 0*2 = 0 Example 3: Input: nums1 = [0,1,0,0,2,0,0], nums2 = [1,0,0,0,3,0,4] Output: 6

A sparse vector is a vector that has mostly zero values, while a dense vector is a vector where most of the elements are non-zero. It is inefficient to store a sparse vector as a one-dimensional array (Approach 1). Instead, we can store the non-zero values and their corresponding indices in a dictionary, with the index being the key (Approach 2). Alternatively, we can represent elements of a sparse vector as an array of pairs for each non-zero value. Each pair has an integer index and a numerical value (Approach 3). const SparseVector = function(nums) { this.nums = nums } SparseVector.prototype.dotProduct = function(vec) { let product = 0 for(i = 0; i < vec.nums.length; i++){ if(vec.nums[i] == 0 || this.nums[i] == 0) continue product += vec.nums[i] * this.nums[i] } return product } Time complexity: O(n) for creating the Hash Map; O(L) for calculating the dot product. Space complexity: O(L) for creating the Hash Map, as we only store elements that are non-zero. O(1) for calculating the dot product. Consider using a list instead so we don't spend time hashing the values. We can also represent elements of a sparse vector as a list of <index, value> pairs. We use two pointers to iterate through the two vectors to calculate the dot product. https://leetcode.com/problems/dot-product-of-two-sparse-vectors/

Given an array nums of size n, return the majority element. The majority element is the element that appears more than ⌊n / 2⌋ times. You may assume that the majority element always exists in the array. Example 1: Input: nums = [3,2,3] Output: 3 Example 2: Input: nums = [2,2,1,1,1,2,2] Output: 2

Boyer-Moore Voting Algorithm https://leetcode.com/problems/majority-element/editorial/

Given an integer array nums and an integer k, return the kth largest element in the array. Note that it is the kth largest element in the sorted order, not the kth distinct element. Can you solve it without sorting? Example 1: Input: nums = [3,2,1,5,6,4], k = 2 Output: 5 Example 2: Input: nums = [3,2,3,1,2,4,5,5,6], k = 4 Output: 4

Quick Select algo gives O(n) time complexity Heap Solution findKthLargest(nums, k) { let minHeap = []; for (let num of nums) { minHeap.push(num); // Ensure that the heap size stays at k if (minHeap.length > k) { minHeap.sort((a, b) => a - b); // Sort in ascending order minHeap.shift(); // Remove the smallest element } } // After processing all elements, the k-th largest element will be at the top of the min heap return minHeap[0]; } Time complexity: O(n⋅log⁡k) Operations on a heap cost logarithmic time relative to its size. Because our heap is limited to a size of k, operations cost at most O(log⁡k). We iterate over nums, performing one or two heap operations at each iteration. Space: O(k)

Given two nodes of a binary tree p and q, return their lowest common ancestor (LCA). Each node will have a reference to its parent node. The definition for Node is below: class Node { public int val; public Node left; public Node right; public Node parent; } According to the definition of LCA on Wikipedia: "The lowest common ancestor of two nodes p and q in a tree T is the lowest node that has both p and q as descendants (where we allow a node to be a descendant of itself)." Example 1: Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 1 Output: 3 Explanation: The LCA of nodes 5 and 1 is 3. Example 2: Input: root = [3,5,1,6,2,0,8,null,null,7,4], p = 5, q = 4 Output: 5 Explanation: The LCA of nodes 5 and 4 is 5 since a node can be a descendant of itself according to the LCA definition. Example 3: Input: root = [1,2], p = 1, q = 2 Output: 1

This is the simple answer. Don't forget you might need to check the height of p and q, then move to equal height, then traverse to the top until matching nodes. function lowestCommonAncestor(p, q) { let a = p, b = q; // Traverse until both pointers meet at the LCA while (a !== b) { // If a reaches null, reset it to q a = a === null ? q : a.parent; // If b reaches null, reset it to p b = b === null ? p : b.parent; } return a; } https://leetcode.com/problems/lowest-common-ancestor-of-a-binary-tree-iii/

Given a string s, return true if the s can be palindrome after deleting at most one character from it. Example 1: Input: s = "aba" Output: true Example 2: Input: s = "abca" Output: true Explanation: You could delete the character 'c'. Example 3: Input: s = "abc" Output: false

Two Pointer var validPalindrome = function(s) { const check = (lo, hi, removed = false) => { while (lo < hi) { if (s[lo] != s[hi]) { if (removed) { return false; } return check(lo+1, hi, true) || check(lo, hi-1, true); } lo += 1; hi -= 1; } return true; }; return check(0, s.length - 1); }; Time: O(n) Space: O(1) https://leetcode.com/problems/valid-palindrome-ii/

Given the root of a binary tree, return the vertical order traversal of its nodes' values. (i.e., from top to bottom, column by column). If two nodes are in the same row and column, the order should be from left to right. Example 1: Input: root = [3,9,20,null,null,15,7] Output: [[9],[3,15],[20],[7]] Example 2: Input: root = [3,9,8,4,0,1,7] Output: [[4],[9],[3,0,1],[8],[7]] Example 3: Input: root = [3,9,8,4,0,1,7,null,null,null,2,5] Output: [[4],[9,5],[3,0,1],[8,2],[7]] Constraints: The number of nodes in the tree is in the range [0, 100]. -100 <= Node.val <= 100

Use a hashmap to keep our column lists. Visit the tree using BSF. Keep min col and max col vars so we can iterate at the end without sorting. class TreeNode { constructor(val, left = null, right = null) { this.val = val; this.left = left; this.right = right; } } class Solution { verticalOrder(root) { const output = []; if (!root) { return output; } // Using an object as a map to store columns const columnTable = {}; const queue = [[root, 0]]; let minColumn = 0, maxColumn = 0; while (queue.length > 0) { const [node, column] = queue.shift(); if (node != null) { if (!columnTable[column]) { columnTable[column] = []; } columnTable[column].push(node.val); minColumn = Math.min(minColumn, column); maxColumn = Math.max(maxColumn, column); queue.push([node.left, column - 1]); queue.push([node.right, column + 1]); } } for (let i = minColumn; i <= maxColumn; i++) { output.push(columnTable[i]); } return output; } } // Example usage const tree = new TreeNode(3, new TreeNode(9), new TreeNode(20, new TreeNode(15), new TreeNode(7))); const solution = new Solution(); console.log(solution.verticalOrder(tree)); Time Complexity: O(N) where N is the number of nodes in the tree. Space Complexity: O(N) where N is the number of nodes in the tree. https://leetcode.com/problems/binary-tree-vertical-order-traversal/

You are given a 0-indexed array of positive integers w where w[i] describes the weight of the ith index. You need to implement the function pickIndex(), which randomly picks an index in the range [0, w.length - 1] (inclusive) and returns it. The probability of picking an index i is w[i] / sum(w). For example, if w = [1, 3], the probability of picking index 0 is 1 / (1 + 3) = 0.25 (i.e., 25%), and the probability of picking index 1 is 3 / (1 + 3) = 0.75 (i.e., 75%). Example 1: Input ["Solution","pickIndex"] [[[1]],[]] Output [null,0] Explanation Solution solution = new Solution([1]); solution.pickIndex(); // return 0. The only option is to return 0 since there is only one element in w.

class Solution { constructor(w) { this.prefixSums = new Array(w.length); let prefixSum = 0; for (let i = 0; i < w.length; ++i) { prefixSum += w[i]; this.prefixSums[i] = prefixSum; } this.totalSum = prefixSum; } pickIndex() { const target = this.totalSum * Math.random(); let low = 0, high = this.prefixSums.length; while (low < high) { const mid = Math.floor((high + low) / 2); if (target > this.prefixSums[mid]) { low = mid + 1; } else { high = mid; } } return low; } } // Example usage const solution = new Solution([1, 3, 4]); console.log(solution.pickIndex()); // Outputs a random index based on the weight Time: constructor: O(n) pickIndex: O(logn) Space: constructor: O(n) pickIndex: O(1) https://leetcode.com/problems/random-pick-with-weight/

You are given a nested list of integers nestedList. Each element is either an integer or a list whose elements may also be integers or other lists. The depth of an integer is the number of lists that it is inside of. For example, the nested list [1,[2,2],[[3],2],1] has each integer's value set to its depth. Return the sum of each integer in nestedList multiplied by its depth. Example 1: Input: nestedList = [[1,1],2,[1,1]] Output: 10 Explanation: Four 1's at depth 2, one 2 at depth 1. 1*2 + 1*2 + 2*1 + 1*2 + 1*2 = 10. Example 2: Input: nestedList = [1,[4,[6]]] Output: 27 Explanation: One 1 at depth 1, one 4 at depth 2, and one 6 at depth 3. 1*1 + 4*2 + 6*3 = 27. Example 3: Input: nestedList = [0] Output: 0

class Solution { depthSum(nestedList) { let queue = nestedList.slice(); // Clone the nestedList to avoid modifying the input let depth = 1; let total = 0; while (queue.length > 0) { let size = queue.length; for (let i = 0; i < size; i++) { let nested = queue.shift(); if (typeof nested === 'number') { total += nested * depth; } else { queue.push(...nested); // Spread operator to add all elements of the nested array to the queue } } depth++; } return total; } } // Example usage const solution = new Solution(); const nestedList = [1, [4, [6]]]; console.log(solution.depthSum(nestedList)); // Output: 27 (1*1 + 4*2 + 6*3) Time: O(n) Space: O(n) https://leetcode.com/problems/nested-list-weight-sum/description/

Given a string s of '(' , ')' and lowercase English characters. Your task is to remove the minimum number of parentheses ( '(' or ')', in any positions ) so that the resulting parentheses string is valid and return any valid string. Formally, a parentheses string is valid if and only if: It is the empty string, contains only lowercase characters, or It can be written as AB (A concatenated with B), where A and B are valid strings, or It can be written as (A), where A is a valid string. Example 1: Input: s = "lee(t(c)o)de)" Output: "lee(t(c)o)de" Explanation: "lee(t(co)de)" , "lee(t(c)ode)" would also be accepted. Example 2: Input: s = "a)b(c)d" Output: "ab(c)d" Example 3: Input: s = "))((" Output: "" Explanation: An empty string is also valid. Constraints: 1 <= s.length <= 105 s[i] is either'(' , ')', or lowercase English letter.

class Solution { minRemoveToMakeValid(s) { // Pass 1: Remove all invalid ")" let openSeen = 0; let balance = 0; let sb = []; for (let i = 0; i < s.length; i++) { let c = s[i]; if (c === '(') { openSeen++; balance++; } else if (c === ')') { if (balance === 0) continue; balance--; } sb.push(c); } // Pass 2: Remove the rightmost "(" let result = []; let openToKeep = openSeen - balance; for (let i = 0; i < sb.length; i++) { let c = sb[i]; if (c === '(') { openToKeep--; if (openToKeep < 0) continue; } result.push(c); } return result.join(''); } } // Example usage const solution = new Solution(); const s = "a)b(c)d"; console.log(solution.minRemoveToMakeValid(s)); // Output: "ab(c)d" Time complexity : O(n), where n is the length of the input string. Space complexity : O(n), where n is the length of the input string. https://leetcode.com/problems/minimum-remove-to-make-valid-parentheses/editorial/

A string can be abbreviated by replacing any number of non-adjacent, non-empty substrings with their lengths. The lengths should not have leading zeros. For example, a string such as "substitution" could be abbreviated as (but not limited to): "s10n" ("s ubstitutio n") "sub4u4" ("sub stit u tion") "12" ("substitution") "substitution" (no substrings replaced) The following are not valid abbreviations: "s55n" ("s ubsti tutio n", the replaced substrings are adjacent) "s010n" (has leading zeros) "s0ubstitution" (replaces an empty substring) Given a string word and an abbreviation abbr, return whether the string matches the given abbreviation. A substring is a contiguous non-empty sequence of characters within a string. Example 1: Input: word = "internationalization", abbr = "i12iz4n" Output: true Explanation: The word "internationalization" can be abbreviated as "i12iz4n" ("i nternational iz atio n").

function validWordAbbreviation(word, abbr) { let i = 0; // Pointer for word let j = 0; // Pointer for abbr while (j < abbr.length) { if (abbr[j] >= 'a' && abbr[j] <= 'z') { // Character must match if (word[i] !== abbr[j]) { return false; } i++; j++; } else { // It's a digit, must not start with zero if (abbr[j] === '0') { return false; } let num = 0; // Parse the number while (j < abbr.length && !isNaN(abbr[j])) { num = num * 10 + parseInt(abbr[j], 10); j++; } i += num; } } return i === word.length; } // Example usage console.log(validWordAbbreviation("internationalization", "i12iz4n")); // Output: true console.log(validWordAbbreviation("apple", "a2e")); // Output: false Time: O(n) Space: O(1) https://leetcode.com/problems/valid-word-abbreviation/

There are n buildings in a line. You are given an integer array heights of size n that represents the heights of the buildings in the line. The ocean is to the right of the buildings. A building has an ocean view if the building can see the ocean without obstructions. Formally, a building has an ocean view if all the buildings to its right have a smaller height. Return a list of indices (0-indexed) of buildings that have an ocean view, sorted in increasing order. Example 1: Input: heights = [4,2,3,1] Output: [0,2,3] Explanation: Building 1 (0-indexed) does not have an ocean view because building 2 is taller. Example 2: Input: heights = [4,3,2,1] Output: [0,1,2,3] Explanation: All the buildings have an ocean view. Example 3: Input: heights = [1,3,2,4] Output: [3] Explanation: Only building 3 has an ocean view.

let findBuildings = function(heights) { let n = heights.length; let answer = []; let maxHeight = -1; for (let current = n - 1; current >= 0; --current) { // If there is no building higher (or equal) than the current one to its right, // push it in the answer array. if (maxHeight < heights[current]) { answer.push(current); // Update max building till now. maxHeight = heights[current]; } } answer.reverse(); return answer; }; Time: O(n) Space: O(1) https://leetcode.com/problems/buildings-with-an-ocean-view/


Related study sets

Video Production Chapter 9 Questions

View Set

CISA Chapter 10 - Network Security and Control

View Set

Case Study 4 (Shortness of Breath, Edema, and Decreased Urine Output) - Prioritization, Delegation, and Assignment

View Set

Summer Reading: Secrets Lies and Algebra

View Set

Extension of the Wrist: Synergist & Antagonist Muscles

View Set

HESI Exit Practice Questions and Rationale (2)

View Set