Leetcode Google
keep a dict of 62 char(52 lowercase and upper case char and 10 number) 2 maps, shortUrlToLong and longUrl to short. decode if exists in shortUrlToLong, if exists return the whatever is stored, if not return the original short url. encode. check if already encoded. generate a random string of 6 chars, keep randoming until it doesn't exists in shortUrlToLong. then set longUrlMap[longUrl] = randstr shortUrlMap[randStr] = longUrl.
535. Encode and Decode TinyURL
keep the cumulative sum in a map and record the occurrence of the cumulative sum. set map[0] = 1 <- THIS IS important at every step check if CumulativeSum-K exists in the map. If it exists, there means there exists subarray that sums up to K.
560. Subarray Sum Equals K
semi brute force, since theres only 4 integer theres only a total of 16 combinations. Use a set to store these integer. then check against the startTime and keep the minimum difference and string. 4 four loops. Convert to minute units. Also check if hour is < 24 and minutes are smaller then 60. Edge case, when all HH:MM are same integer. just return.
681. Next Closest Time
Find the maximum occurrence of int value, this is the target. If target < number of dominos return -1. Now every step check if A[i] or B[i] == target, if not check the other side, if it is increment either a swap or b swap, else return -1; Take max of aswap bswap
1007. Minimum Domino Rotations For Equal Row
Binary search. left is the maximum element in the array, that's the minimum capacity needed. right is the sum of the array, 1 day shipment. pass m and input array to a helper to see if with m capacity you can finish the shipment in D days or less. if yes, then move left, if no then move right. NOTE, if yes(r = m) else (l = m+1), r=m because m could be the only possible solution.
1014. Capacity To Ship Packages Within D Days
use 2 ptr. one to look at previous(initialize at head) and next(head->next). while(true) 3 cases: insertval >= previous && insertval <= next previoux > next && insertVal < next previous > next && insertVal > next set previous->next = new Node(insertval, next) and break. Set a found to be true; and terminate while loop else previous = previous->next, next = next->next; if found is false, that means every value is the same, then just do previous->next = new Node(insertval, next) return head
708. Insert into a Cyclic Sorted List
For and while loop. use a for loop to iterate through the lines, and while loop to iterate through every character inside the line. use a blockComment bool variable to indicate whether your in a block, also use a newline variable to store the uncommented code 4 cases for every line. if (line.substr(i , 2) == "//" and not in block") break elseif (line.substr(i , 2) == "/* and not in block' ) block = true i++; elseif (line.substr(i , 2) == "*/" and not in block' ) block = false i++; elseif(block == false) newline += line[i] i++ before the end of the while loop(this is important!) after whilte loop exit, check if (block == false && newline > 0) if so push this to answer vector, and set newline to "". return answer;
722. Remove Comments
Recursion: If there are candies need to be crushed horizontally use a variable to mark it as need to be recursed again, keep doing this until there no candy to crushed. ex. todo? : return candyCrush(board) : return board use -abs(board[row][col]) to mark as candy that need to be crushed, to help with the edge case where row and col intersect to be crushed for horizontalcheck, check abs(board[row][col] == abs[row][col+1] == abs[row][col+2] for vertical check abs(board[row][col] ==abs(board[row+1][col] == abs(board[row+2][col] for the crushing part. Use 2 pointer, 1 pointer to point the currentNegativeRow, and 1 pointer to go up the cols. start at col = 0; col++ and row = rowMax-1, row--; to crush 1 column at a time. if board[row][col] > 0, board[negativeRow][col] = board[row][col] and negativeRow--; after this column crushed, set all index between negative row and 0 to be 0. I.e. board[negativeRow... 0] [col] = 0
723. Candy Crush
Use a set in c++ to store the booking time. In book function first use lower_bound(start, end) to find the immediate calendar that's greater the pair given. check if overlaps. next check if the previous of lower_bound overlaps. Essentially its finding the element in the book that's greater then the time given, then check its left and right.
729. My Calendar I
use two maps, one to map word[I] to pattern [I] and another for pattern[I] to word[I]. then check both way if the pattern matches, if not return false;
890. Find and Replace Pattern
Count overlap, use two vector one vector to store the currently booked events(start and end pairs). another vector to store the overlapping interveals of the current events. when book an event check ifs already overlapped with time inside the overlapping vector, if so return false. else check if its overlapped with whats inside the calendar, if so insert the overlapping interval to the overlapping vector, which is (max(start,overlap[I].start), min(end, overlap[I].end) next don't forget to add to calendar and return true.
731. My Calendar II
Union find Create a helper function Find. Find(map<string,string> link, word) if (!link[word] || link[word] = word) return word; else find(link[word]); now go through the 2d vector, and find the root of every node in pair, if the root are not the same, link them together(LINK THE ROOT NOT THE NODE) now go through the two words list, and compare the root of every ith node, if not the same return false last return true
737. Sentence Similarity II
use a stack to store index. Iterate througth the input. At every step A.check whether value at i is greater then the value at top. If so, answer[i] = i-top, pop top, and keep checking until stack is empty or i is smaller then top. B. push index to stack.
739. Daily Temperatures
Construct a graph with the Tree. Store the graph in a 2d vector such that vector[i] will contain the list of neights of i. Make sure to link both parent a child. Now bfs starting at vector[k], to determine if its a leaf, check if it only has a neighbor AND ITS NOT EQUAL TO THE ROOT(the root can have 1 neighbor and its not a leaf). Return the first leaf found. If not push all its neighbors to bfs queue and add its neighbors to visited set.
742. Closest Leaf in a Binary Tree
Use DFS Create an adjacency list for all node using unordered map. map<node, List<pair<neighbourNode, neighbourCost>> creater another map to hold the cost from K to every Node, initialize the cost to be INT max, Now dfs starting at Node K, and include cost as variable to dfs function(set to 0 initialliy) DFS(adjacentList, NodeCostMap, Node, cost) check NodeCost[Node] > cost; return set NodeCost[Node] = cost; for (neighbours in adjacencyList[node]) dfs(adjace, nodeCostMap, neighbours, neighbours.cost + cost) After dfs all the node, pick the max of all the NodeCostMap, if answer is int_max return -1; NOTE* to make the DFS faster, sort the neighbours from smallest to highest in terms of cost
743. Network Delay Time
for every row, store the top left and top right coord. For example row1, col1 and row1 col2. An unique int can be created by col1 * 200 + col2. Store this in an map with occurrence. Everytime another is found add the count to rectangleCount(since another rectangle has been found), and then increment count. Note if there are 3 counts already, and a 4th one is found. You will add 3 to rectangle count. Since the 4th pair of coordinates when paired with the previous 3 counts would create 3 rectangles.
750. Number Of Corner Rectangles
Use a max heap to store(count, char). While pushing into this heap, if any charCount is greater then (string.length+1)/2 return empty. Now iterate N times, everytime take the char with the largest count. Edge case, check if the current largest char is the same as the previous largest char, if so, take 2nd largest. Make sure to decrement the counts inside the heap.
767. Reorganize String
Inorder for the first x elements to form chunk, they must all sum up to (0...x). Therefore keep adding x to a cumulative sum check every step if the cumulative sum is equal to(0+1+...x) if it is that means this can form a chunk. Increment chunk count.
769. Max Chunks To Make Sorted
Recursion. Base case, if root== Null return vector<null,null> Case 1. Root->Val > target; vector[1] = root; auto leftTree = recurse(root->left, target) root->left = lefttree[1] // all the nodes in left that's greater then target vector[0] = lefttree[0] Case 2. Root->val <= target; vector[0] = root; auto rightTree = recurse(root->right, target) root->right = rightTree[0] // all the nodes in the right that's smaller then target; vector[1] = rightTree[1]; return vector
776. Split BST
Use 2 ptr. First check if start.removeAllX == end.removeAllX. Since The replacement will not switch the order of R and X. Now use two ptrs twice, once to Check L and once to Check R find the first occurrence of L in start and end, the index of start must be greaterindex of end, since XL -> LX, and keep doing this until end now reset points check for R in start and end the index of start must be smaller then the index of end, since RX -> XR
777. Swap Adjacent in LR String
Use DFS. create a color vector of size N initialized as 0; use a for loop to iterate through the input. for (node in input) if color(node) == 0 && !validMark(node, 1) return false; return true create a helper function validMark, that marks the node and its neighbor using dfs validMark(node, color) if (already colored(node)) { return node.color == color node.color = color for (neigh in node) if (!validMark(neigh, -color) return false; return true; }
785. Is Graph Bipartite?
keep a map of (char, vector<string>>) to store words where char corresponds to the start char of its vector<strings> Ex. words = ["a", "bb", "acd", "ace"], becomes map ('a', (a, acd, ace)); map ('b', (bb)); iterate through S, check each character, and check it inside the map, then modify remove the first character in the vector<strings> and insert it again to the map at key = beginning(string> after deleting the first character. when the last character is deleted increment answer by 1
792. Number of Matching Subsequences
X must be 1 greater or equal to O; If X wins, X must be 1 greater then O If O wins, O must be equal to X; use a win helper function to determine whether X wins or O wins, Horitonally vertically or diagonnally. make sure only one player can win
794. Valid Tic-Tac-Toe State
suppose n glass is poured; A[0][0] will take one glass and (n-1)/2 glasses will be poured to its left and right neighbour. Therefor set A[0][0] as poured; Now it will have Remaining = (A[row][col] - 1 )/2. If positive then Then set A[row+1][col] = Reminaing and A[row+1][col+1] remaining. iterate throught all the rows Return min(1, and A[row][col]
799. Champagne Tower
Two Solution 1. Check every single word, and use a helper function to check of A is stretchy of B. three cases: for i in A beginning of stretchy A[i] == B[j] increment j mid of stretchy if A[i] == A[i-1] == A[i]+1 do nothing(for loop will increment i) end of stretchy if A[i-2] == A[i-1] == A[i-0] do nothing... compare j to size of B. 2. Compress S to the format of letters and count and store it in a map ex. heeellooo, map = (helo, {1,3,2,3}) now take every word in words and compress it, check if its the same as whats inside the map. If it is compare the counts, if S[i] < W[i](false), if (S[i] >= 3) or (S[i] < 3 && S[i] == W[i]) continue.
809. Expressive Words
iterate throught the linkedlist. If currentNode is in Gset, and currentNext==NULL or CurrentNext does not exist in Get, incrememt count, since this is the end of a connected component.
817. Linked List Components
sort the index from largest to smallest, and use a pair<indexValue, actual index> . replace from behind. so that you don't have to worry about index. if (S.substr(i, source.length()) == source) S = S.substr(0, i) + target + S.substr(i + source.length()); https://leetcode.com/problems/find-and-replace-in-string/discuss/130587/C%2B%2BJavaPython-Replace-S-from-right-to-left
833. Find And Replace in String
Create a 2d vector of 2N+1 * 2N+1 to store the difference. since the difference between a coordinate in A and B can go from -N to N. Compare every coordinates in A and B that equals to 1. Compute the difference of its x and y coordiates as xDif and yDif. Increment Array[xDif][yDif]++. Then Array[xDif][yDif] will contain the overlaps of you shift by xDif and yDif Now either go through the 2d vector to find the Max as the answer, or you can compute the answer along the way. There's a more clever solution here. https://leetcode.com/problems/image-overlap/discuss/130623/C%2B%2BJavaPython-Straight-Forward
835. Image Overlap
Edge case, K = 0, or N >= K+W return 1; We want to calculate the probability of number ending in K to N; Notice that P[x] = (P[x-1] + P[x-2] ... P[x-w])/w; Then we can keep a cum sum variable of Wsum(initialize at 1), such that dp[i] = Wsum/w and Wsum is the sum of previous W dps. We can only do this while i < k, when i >k we no longer accum Wsum, since dp[i] to dp[n] is independent of each other when i >= k; for k < i <= N, we sum the dp[i] since this is the probability we care about.
837. New 21 Game
keep track of maxMountain, leftMountain and rightMountain iterate through the array and comparing the current against previous. Case1. Current > previous, if both right and left are nonzero, set to zero. this is a new mountain and increment left. Case2. Current < previous, if left != 0, increment right, and maxMountain = max(maxMountain, left+right+1) Case3. Current == previous, set left and right = 0;
845. Longest Mountain in Array
sort and use map to store counts of each int. start from the smallest and try to form a consecutive of Size w, decrement the counts inside the map. if at anypoint a consecutive integer cannot be found return false. Last step check if map is empty.
846. Hand of Straights
sort the cars in positions, and compute the time it takes to arrive to target. start from the car closest to target and iterate the array from closest to target to farthest. Keep track of the largest speed encountered so far. If the car[x] takes longer time to get to target then the largest speed(max_speed[car[x+1..end]). Car[x] will form a separate fleet of its own. Since its always slower and farther. KEY thing is to start from index.end to 0 not the other way around.
853. Car Fleet
use a sorted set to store the currently occupied seats. The compare every adjacent two seats and store the the one with maximum distance and seat. At the end check to see if the left most seat and right most seat are still viable. (compare the maximum distance so far to (leftmostSeat-0) and (N-1 -rightMostseat)
855. Exam Room
Use dp dp[x][y] store the points of alex, from input[x...y]. base case( y- x == 1) size 2 array, dp[x][y] == abs(piles[y]-piles[x]), since this is alex's move(even size array) and alex will always pick the bigger number then create dp on [x+1][y] and [x][y-1] if odd array (opponent) dp[x][y] = min(-piles[x] + dp[x+1][y], -piles[y] + dp[x][y-1] if even array (alex) dp[x][y] = max(piles[x] + dp[x+1][y], piles[y] + dp[x][y-1]
877. Stone Game
sort then use 2 pointer. try to pair the smaller with the largest, if possible, then incremeber small pointer(2 man on ship). If not decrement big pointer(big man boat alone). Both cases increase boat count.
881. Boats to Save People
for preorder. root is at array[0] and postOrder, root is at array[last] if you can find the range of the array containing left and right subtree we can keep recurse. since for preorder root is at array[0], that means array[1] is the root of its left subtree, then suppose its subtree had a length of L, then array[1] to array[L+1] is the left subtree of preorder. We can find the length of the left subtree in the postOrder by looking for the element of left subtree root which is array[1] of preorder. once we find L. root.left = (preorder[1, L+1], postorder(0, L) root.right = (preorder(L+2, end), postOrder(L+1, end-1)
889. Construct Binary Tree from Preorder and Postorder Traversal
Used two variable index and quantity. Index will be pointing to the element that will be popped next, and quantity will be (index+1) which indicates how many of that element can be popped. While(index < size) 1. if number you want to pop is greater then array[index] + q, then you have to pop all elements, so index = index+2, q= 0; else modify q to become q+n, and return array[index+1] other case return -1;
900. RLE Iterator
2 pointer idea, initialize the left point at 0. Iterate throught the array of trees with a for loop starting at index i = 0(this will be right pointer). Keep insert these values to a hashmap of(number, occurrence). Check if there are more then two values in hashmap, if there is keep delete value at point[left] and increment left, until theres exactly two values. if there are less than or equal to two values. maxSoFar = max(maxSoFar, right-left+1) After you go through the array, return maxSoFar
904. Fruit Into Baskets
Create an empty map that's used to store the leader in vote at each time: topVoterMap. Create a second map to keep track of number of votes for each person as you go through the person and votes: voteMap: Go through the person and times, map and increment the votes for each person. During each iteration check if the vote for the current person is greater then the previous leader. If so set topVoterMap[currentTime] to be the current leader, topVoterMap[currentTime] = previous leader.
911. Online Election
DP Create a 2d array with [size+1][2], the idea is that DP[x][1] will contain the minimum of flips when the xth number is 1, and DP[x][0] will contain the minimum number of flips when the xth number is 0. base case :DP[0][0] and DP[0][1] = 0 now go through the string Case1: when number is 0; if you want to keep this number as 0, DP[x][0] = DP[x-1][0], no flips required already 0 if you want to flip this number to 1, then DP[x][1] = min(DP[x-1][0] + 1, DP[x-1][1] +1) Case2: when number is 1; if you want to keep this number as 1, DP[x][1] = min(DP[x-1][0], DP[x-1][1] if you want to flip this number to 0, then DP[x][0] = DP[x-1][0] + 1 now return the min(DP[size][0], DP[size][1]))
926. Flip String to Monotone Increasing
DP Suppose on a 3 by 3 square. MinPathSum[2][x] = [2][x] + min([3][x-1], [3][x], [3],[x+1] we start from the second last row and overwrite the original input matrix with a dp matrix. the answer will be the minimum of first row.
931. Minimum Falling Path Sum
For both solution create a setting mapping the possible jumps. DP solution 1 (personal solution); Create a 2d dp array DP, where DP[x][y] indicate the number of possible moves when you start at position x and can move y times. Then the sum for N moves, is sum of DP[0-9][N-1]; The base case for DP is [DP][x][0] = and DP[x][1] = possibles jumps for x; DP[x][y] = sum neighbours of X x' DP[x'][y-1]; DP solution 2(recommended); Base Case N = 1; return 10; create two arrays, DP1 and DP2, DP1 will contain the number of moves when you arrive at number X, (DP[5] will always be 0, since its unreachable), so DP1 will be size 10. DP2 will be an intermediate array to store the result after 1 more moves. Example dp2[0] = dp[4] + dp[6]; dp2[1] = dp[6] + dp[8]; dp2[2] = dp[7] + dp[9]; dp2[3] = dp[4] + dp[8]; dp2[4] = dp[0] + dp[3] + dp[9]; dp2[6] = dp[0] + dp[1] + dp[7]; dp2[7] = dp[2] + dp[6]; dp2[8] = dp[1] + dp[3]; dp2[9] = dp[2] + dp[4]; for(int j=0; j<10; j++) {dp[j] = dp2[j]}
935 Knight Dialer
Classical Recursion question. Case1: NULL, return 0; Case2: if root between L and R, recurse on root->val + f(root->left, L, root->val) + f(root->right, root->val, R) Case3: if root < L, recurse on f(root->right, L, R) Case4: if root > R, recurse on f(root->left, L, R)
938 Range Sum of BST
Count diagonal, for every two points that are diagonal(just check they do not share x or y axis) look for the missing 3rd and 4th points, this can be obtained by abs(x1,y2) and (x2,y1) if they do exist compute the area and keep the minimum
939 Minimum Area Rectangle
Union Find or DFS: Similar to count island, the answer is number of points - number of islands Union Find: for a point(x,y), find(x) and find(y) if they're not equal, then connect x to y and minus 1 to the islands. find(integer), if integer does not exist, then set integer to root. If it does exist, link the integer to root. and return the root answer to find(integer) *TRICK add 10k to the value of Y, so X will never equal to Y. and you can always tell in the union map that >10k is the col and <10k is the row. DFS: create a rowset and colset based on index, where rowset[0] will contain the indexes of the input that has 0 as row value. this is like adjacent matrix now dfs on the first element, and make sure to push all its adjacent index into the dfs, and add the index to a visited set to prevent future duplicate access.
947 Most Stones Removed
Classic Recursion: 1. Base Cases: Both null, one side not null and not equal. 2. Recurse on flipEqual(A->left, B->right) AND flipEqual(A->right, B->Left) OR (A->left, B->left) AND (A->right, B->right) *2nd case of for equivalent tree
951 Flip Equivalent Binary Tree
Use heap or quickselect to get top K
973. K Closest Points to Origin
DFS. If leaf = 0, it needs 1 move from parent, if it has X greater then 0, then it needs to move x-1 coins to parent. Therefore at every node. We need to move abs(dfs(node.left)) + abs(dfs(node.right)) to its or from children. Then at this level we have an excess/deficit of node.val + dfs(node.left) + dfs(node.right) - 1
979. Distribute Coins in Binary Tree
use map (key, pair(value, int) binary search on the pair to find the one thats smaller then the timestamp provided but closest.
981. Time Based Key-Value Store
2 ptrs. Compare aptr and bptr, if they don't stack, either shift a or b. If they do stack, push the max(a.start, b.start) min(a.end, b.end) then increment either A or B
986. Interval List Intersections