NonN-all Flashcards

1
Q

There is a ball in a maze with empty spaces (represented as 0) and walls (represented as 1). The ball can go through the empty spaces by rolling up, down, left or right, but it won’t stop rolling until hitting a wall. When the ball stops, it could choose the next direction.

Given the m x n maze, the ball’s start position and the destination, where start = [startrow, startcol] and destination = [destinationrow, destinationcol], return true if the ball can stop at the destination, otherwise return false.

You may assume that the borders of the maze are all walls (see examples).

Input: maze = [[0,0,1,0,0],[0,0,0,0,0],[0,0,0,1,0],[1,1,0,1,1],[0,0,0,0,0]], start = [0,4], destination = [4,4]
Output: true
Explanation: One possible way is : left -> down -> left -> down -> right -> down -> right.

A
class Solution:
    def hasPath(self, maze: List[List[int]], start: List[int], destination: List[int]) -> bool:
        ROWS, COLS = len(maze), len(maze[0])
        visitedStops = set() 
        directions = [(0, 1), (0, -1), (1, 0), (-1, 0)]

        #We run dfs from stop sets (the "stop sets when hit walls") basically. We don't care about the cells in the middle to be added to visited, only the cells near walls.
        def dfs(r, c):
            #If we try to visit the stopSet again, return False
            #Since when we run into the stop, we will do a dfs and have attempted.
            if (r, c) in visitedStops:
                return False
            visitedStops.add((r, c))
            #If this stop is the destination
            if [r, c] == destination:
                return True
            #Try all possible directions
            for dr, dc in directions:
                #The ball starts at r, c. Important!
                newR, newC = r, c
                #Roll as far as we can, until we hit a wall. Let's check if it even makes sense to roll in that 
                #Particular direction. Let's do that by checking newR + dr, newC + dc in the while loop
                #Otherwise we prematurely set newR = newR + dr, newC = newC + dc, and then calling
                #dfs on that premature out of bounds position will cause confusion.
                #Whereas if we set newR, newC to be r, c above, the dfs(r, c) will just return False since that stop is already in visited.
                while newR + dr >= 0 and newR + dr < ROWS and newC + dc >= 0 and newC + dc < COLS and maze[newR + dr][newC + dc] != 1:
                    newR += dr
                    newC += dc
                #We rolled and hit a stop. Now if the recursive call from this stop returned True, we can return True
                if dfs(newR, newC):
                    return True
            return False
        return dfs(start[0], start[1])
        #Runtime: O(mn) #Visit all the cells potentially.
        #Space: O(mn) upper bound but in actuality, it's a combination of 1) number of stops
                #2) longest straight path -> recursion stack
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

You are given the string croakOfFrogs, which represents a combination of the string “croak” from different frogs, that is, multiple frogs can croak at the same time, so multiple “croak” are mixed.

Return the minimum number of different frogs to finish all the croaks in the given string.

A valid “croak” means a frog is printing five letters ‘c’, ‘r’, ‘o’, ‘a’, and ‘k’ sequentially. The frogs have to print all five letters to finish a croak. If the given string is not a combination of a valid “croak” return -1.

Input: croakOfFrogs = “crcoakroak”
Output: 2
Explanation: The minimum number of frogs is two.
The first frog could yell “crcoakroak”.
The second frog could yell later “crcoakroak”.

A
class Solution:
    def minNumberOfFrogs(self, croakOfFrogs: str) -> int:
        counts = {} #maps the char to the count
        for c in "croak": #initialize counts to zero to start.
            counts[c] = 0
        CROAK_STRING = "croak"

        res, curFrogs = 0, 0
        for c in croakOfFrogs:
            #1) Count the number of each character. Do this for every character.
            counts[c] += 1
            #2) Increment/decrement frogs as needed.
            if c == "c":
                curFrogs += 1
            elif c == "k":
                curFrogs -= 1
            
            res = max(res, curFrogs)
            #length 5 operation
            for i in range(len(CROAK_STRING) - 1):
                #3) If at any point there are more subsequent letters than previous (more Rs than Cs, etc..), that is an issue, so return -1
            #example: crr #<- this is invalid!!
                if counts[CROAK_STRING[i + 1]] > counts[CROAK_STRING[i]]:
                    return -1
        #4) At the end, we expect there to be no more croaking frogs
        #   Invalid example: croakc #this is invalid.
        # And that the counts of everything match!
        if curFrogs == 0 and all(count == counts["c"] for count in counts.values()):
            return res
        return -1
        #Runtime: O(n) just iterating through the String
        #Space: O(5) -> O(1) for the counts map
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

You have a browser of one tab where you start on the homepage and you can visit another url, get back in the history number of steps or move forward in the history number of steps.

Implement the BrowserHistory class:

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

Input:
[“BrowserHistory”,”visit”,”visit”,”visit”,”back”,”back”,”forward”,”visit”,”forward”,”back”,”back”]
[[“leetcode.com”],[“google.com”],[“facebook.com”],[“youtube.com”],[1],[1],[1],[“linkedin.com”],[2],[2],[7]]
Output:
[null,null,null,null,”facebook.com”,”google.com”,”facebook.com”,null,”linkedin.com”,”google.com”,”leetcode.com”]

Explanation:
BrowserHistory browserHistory = new BrowserHistory(“leetcode.com”);
browserHistory.visit(“google.com”); // You are in “leetcode.com”. Visit “google.com”
browserHistory.visit(“facebook.com”); // You are in “google.com”. Visit “facebook.com”
browserHistory.visit(“youtube.com”); // You are in “facebook.com”. Visit “youtube.com”
browserHistory.back(1); // You are in “youtube.com”, move back to “facebook.com” return “facebook.com”
browserHistory.back(1); // You are in “facebook.com”, move back to “google.com” return “google.com”
browserHistory.forward(1); // You are in “google.com”, move forward to “facebook.com” return “facebook.com”
browserHistory.visit(“linkedin.com”); // You are in “facebook.com”. Visit “linkedin.com”
browserHistory.forward(2); // You are in “linkedin.com”, you cannot move forward any steps.
browserHistory.back(2); // You are in “linkedin.com”, move back two steps to “facebook.com” then to “google.com”. return “google.com”
browserHistory.back(7); // You are in “google.com”, you can move back only one step to “leetcode.com”. return “leetcode.com”

A
class BrowserHistory:

    def \_\_init\_\_(self, homepage: str):
        self.history = [homepage]
        self.curIndex = 0
        self.curLength = 1
        
    #[1, 2, 3] 
    #       i = 2     
    def visit(self, url: str) -> None:
        #Check if we should be appending or replacing
        # 3 < 4, we need to append.
        if len(self.history) < self.curIndex + 2:
            self.history.append(url)
        else:
            #replace the elt at the next index over
            self.history[self.curIndex + 1] = url
        
        #Advance curIndex to the next index
        self.curIndex += 1
        #Compute the new true length. This is mainly used for the forward operation
        self.curLength = self.curIndex + 1
        #Example: [1, 2, 3, 4 5]
        #                i=2
        #We replace history with [1, 2, 3, 6  5], then i advances to i = 3
                                          #i=3
        #so the curLength is i + 1 after the advance (length 4), since 6 is our last element.

    def back(self, steps: int) -> str:
        self.curIndex = max(self.curIndex - steps, 0)
        return self.history[self.curIndex]

    def forward(self, steps: int) -> str:
        #Go up to the last element of our curLength. Think of it as basically the "length," so last element is curLength - 1.
        self.curIndex = min(self.curIndex + steps, self.curLength - 1)
        return self.history[self.curIndex]
    #Runtime: O(1) for every single operation, because we "soft delete" for visit
    #Space: O(n) for the browser history, which can potentially contain more elements than we want (stale soft-deleted data) That's fine..

Your BrowserHistory object will be instantiated and called as such:
# obj = BrowserHistory(homepage)
# obj.visit(url)
# param_2 = obj.back(steps)
# param_3 = obj.forward(steps)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Cousins in Binary Tree

Given the root of a binary tree with unique values and the values of two different nodes of the tree x and y, return true if the nodes corresponding to the values x and y in the tree are cousins, or false otherwise.

Two nodes of a binary tree are cousins if they have the same depth with different parents.

Note that in a binary tree, the root node is at the depth 0, and children of each depth k node are at the depth k + 1.

Input: root = [1,2,3,4], x = 4, y = 3
Output: false

A
# Definition for a binary tree node.
# class TreeNode:
#     def \_\_init\_\_(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def isCousins(self, root: Optional[TreeNode], x: int, y: int) -> bool:
        #Cousins if on the same level but different parents
        q = deque() #(the actualNode, parent value)
        q.append((root, None)) #no parent initially
        while q:
            levelMap = {} #key all the node values in current level, value is the parent that it came from.
            for _ in range(len(q)):
                curNode, parent = q.popleft()
                levelMap[curNode.val] = parent
                if x in levelMap and y in levelMap and levelMap[x] != levelMap[y]:
                    return True
                
                if curNode.left:
                    q.append((curNode.left, curNode.val))
                if curNode.right:
                    q.append((curNode.right, curNode.val))
        return False
        #O(n)
        #O(h)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Lowest Common Ancestor of a Binary Tree

Given a binary tree, find the lowest common ancestor (LCA) of two given nodes in the tree.

According to the definition of LCA on Wikipedia: “The lowest common ancestor is defined between two nodes p and q as the lowest node in T that has both p and q as descendants (where we allow a node to be a descendant of itself).”

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.

A
# Definition for a binary tree node.
# class TreeNode:
#     def \_\_init\_\_(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution:
    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if not root:
            return None

        #Goal is to find p or q
        #Returns p or q
        if root == p or root == q:
            return root

        #If not found, try to find p and q in subtrees respectively.
        ##LeftNode and rightNode will return the subtrees that are rooted at p and q respectively, since we have the root == p or root == q condition up above
        ##The goal is to find p and find q. In both left and right subtrees, we try to find both.
        leftNode = self.lowestCommonAncestor(root.left, p, q)
        rightNode = self.lowestCommonAncestor(root.right, p, q)

        #If able to find both
        if leftNode and rightNode:
            return root #the root is the LCA
        
        #If not able to find both, so both are on the same side. Therefore, the anchor that we found on the one side is LCA.
        if leftNode:
            return leftNode
        if rightNode:
            return rightNode
        #Runtime: O(n)
        #Space: O(h)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Single Element in a Sorted Array

You are given a sorted array consisting of only integers where every element appears exactly twice, except for one element which appears exactly once.

Return the single element that appears only once.

Your solution must run in O(log n) time and O(1) space.

Input: nums = [1,1,2,3,3,4,4,8,8]
Output: 2

A
class Solution:
    def singleNonDuplicate(self, nums: List[int]) -> int:
        l, r = 0, len(nums) - 1
        while l <= r:
            m = l + (r - l) // 2
            if ((m - 1) < 0 or nums[m] != nums[m - 1]) and (m + 1 == len(nums) or nums[m] != nums[m + 1]):
                return nums[m]
            leftSize = m - 1 if nums[m - 1] == nums[m] else m
            if leftSize % 2:
                r = m - 1
            else:
                l = m + 1
        #O(log n)
        #O(1)
    #If index m is 3, the values to the left are 0 1 2. So it would be m normally. But if nums[m - 1] = nums[m], then the size is actually m - 1 since we skip the elt to the left.

#What if m - 1 is out of bounds? So in this case, m was 0. Since array is sorted, m - 1 is the last element, so we take m. Therefore, leftSize = m = 0.

The unique number is on the side that has odd number of elts (after duplicate with m crossed out).
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Implement Minesweeper

  • Example Input: 3, 5, [(0,2), (1,2), (2,2)]
    • This indicates the number of rows, number of columns, and mine_coordinates
  • Implement the following functions:
  • def __init__(self, ROWS, COLS, mine_coordinates): initialize the game with these inputs.
  • def get_board(self): get the board in its current state
  • def reveal(self, r, c): click at r, c, and recursively reveal everything that we can reveal. If bomb, return immediately and print “game over”
A
class Game:
    def \_\_init\_\_(self, ROWS, COLS, mine_coordinates):
        self.grid = [[0] * COLS for r in range(ROWS)]
        self.mask = [[False] * COLS for r in range(ROWS)]
        self.directions = [(0,1), (0, -1), (1,0),(-1, 0), (1, 1), (-1, 1), (1, -1), (-1, -1)]
        for r, c in mine_coordinates:
            self.grid[r][c] = "B"
        self.ROWS = ROWS
        self.COLS = COLS
        
        for r in range(ROWS):
            for c in range(COLS):
                if self.grid[r][c] != "B":
                    self.grid[r][c] = self.computeNumber(r, c)
    #computes the number to store in a particular cell
    def computeNumber(self, r, c):
        total = 0
        for dr, dc in self.directions:
            neiR, neiC = r + dr, c + dc
            if neiR >= 0 and neiR < self.ROWS and neiC >= 0 and neiC < self.COLS and self.grid[neiR][neiC] == "B":
                total += 1
        return total
    
    def reveal(self, r, c):
        if self.grid[r][c] == "B":
            self.mask[r][c] = True
            print("Game Over")
            return
        self.mask[r][c] = True
        for dr, dc in self.directions:
            neiR, neiC = r + dr, c + dc
            #self.mask[neiR][neiC] will be True if already revealed and that acts as our visit set.
            if neiR >=0 and neiR < self.ROWS and neiC >= 0 and neiC < self.COLS and not self.mask[neiR][neiC] and self.grid[neiR][neiC] != "B":
                self.reveal(neiR, neiC) #recursively reveal
    
    def get_board(self):
        visibleBoard = [["-"] * self.COLS for r in range(self.ROWS)]
        for r in range(self.ROWS):
            for c in range(self.COLS):
                if self.mask[r][c]:
                    visibleBoard[r][c] = self.grid[r][c]
                #Otherwise it'll default to a "-"
        return visibleBoard
    #Runtime: O(mn)
    #Space: O(mn)

#Example
# minesweeper = Game(3, 5, [(0, 2), (1, 2), (2, 2)])
# print(minesweeper.get_board())
# minesweeper.reveal(0, 0)
# print(minesweeper.get_board())
# minesweeper.reveal(0, 4)
# print(minesweeper.get_board())
# minesweeper.reveal(0, 2)
# print(minesweeper.get_board())

[['-', '-', '-', '-', '-'], ['-', '-', '-', '-', '-'], ['-', '-', '-', '-', '-']]
# [[0, 2, '-', '-', '-'], [0, 3, '-', '-', '-'], [0, 2, '-', '-', '-']]
# [[0, 2, '-', 2, 0], [0, 3, '-', 3, 0], [0, 2, '-', 2, 0]]
# Game Over
# [[0, 2, 'B', 2, 0], [0, 3, '-', 3, 0], [0, 2, '-', 2, 0]]
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Stone Game, but Parity can be even OR odd.

Alice always goes first

Bob ALWAYS picks the maximum value that’s available from the ends

Return the max sum that Alice can earn from this game

A
def stoneGame(piles):
    dp = {} #(l, r) -> Alice max
    def dfs(l, r, isATurn):
        if l > r:
            return 0
        if (l, r) in dp:
            return dp[(l, r)]
        if isATurn:
            dp[(l, r)] = max(piles[l] + dfs(l + 1, r, False), piles[r] + dfs(l, r - 1, False))
            return dp[(l, r)]
        else:
            if piles[l] > piles[r]:
                #What remains for Alice is l + 1 to r to choose from
                dp[(l, r)] = dfs(l + 1, r, True)
                return dp[(l, r)]
            else:
                #What remains for Alice is l, r - 1 to choose from
                dp[(l, r)] = dfs(l, r - 1, True)
                return dp[(l, r)]
    return dfs(0, len(piles) - 1, True)
    #Runtime: O(n^2) for l and r values
    #O(n^2) for dp cache
#Even
piles = [3, 7, 2, 1]
print(stoneGame(piles)) # answer is 8
#Odd
piles = [3, 7, 1] #answer is 4
print(stoneGame(piles))

#Odd
piles = [7, 2, 1, 6, 2, 8, 5] #answer should be 22
#A:7 8 6 1 -> 22
#B:5 2 2
print(stoneGame(piles))

#Even
piles = [7, 2, 1, 6, 2, 8, 5, 3] #answer should be 23
#A 7 2 6 8 -> 23
#B 1 2 5 3
print(stoneGame(piles))
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Predict the Winner

You are given an integer array nums. Two players are playing a game with this array: player 1 and player 2.

Player 1 and player 2 take turns, with player 1 starting first. Both players start the game with a score of 0. At each turn, the player takes one of the numbers from either end of the array (i.e., nums[0] or nums[nums.length - 1]) which reduces the size of the array by 1. The player adds the chosen number to their score. The game ends when there are no more elements in the array.

Return true if Player 1 can win the game. If the scores of both players are equal, then player 1 is still the winner, and you should also return true. You may assume that both players are playing optimally.

Input: nums = [1,5,2]
Output: false
Explanation: Initially, player 1 can choose between 1 and 2.
If he chooses 2 (or 1), then player 2 can choose from 1 (or 2) and 5. If player 2 chooses 5, then player 1 will be left with 1 (or 2).
So, final score of player 1 is 1 + 2 = 3, and player 2 is 5.
Hence, player 1 will never be the winner and you need to return false.

A
class Solution:
    def PredictTheWinner(self, nums: List[int]) -> bool:
        dp = {} #(l, r): maxDifference of current player - other player, from numbers between i to j.

        def dfs(l, r):
            if l == r:
                return nums[l]
            if (l, r) in dp:
                return dp[(l, r)]
            #The maximum difference for dp[(l, r)] is. The max we can get from an end, minus the max difference
            #that the OTHER player can get that's in the other player's benefit. This is minimax!
            dp[(l, r)] = max(nums[l] - dfs(l + 1, r), nums[r] - dfs(l, r - 1))
            return dp[(l, r)]
        return dfs(0, len(nums) - 1) >= 0
        #O(N^2)
        #O(N^2)
            

        # def find(i, j):
        #     if (i, j) not in dp:
        #         if i == j:
        #             return nums[i]
        #         dp[i,j] = max(nums[i]-find(i+1, j), nums[j]-find(i, j-1))
        #     return dp[i,j]

        # return find(0, len(nums)-1) >= 0
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

In a video game player starts at beginning of maze, several paths can take to next level of game. Max points from top to bottom of path? CAN BE NEGATIVE VALUES. Using milestone class game = Milestone(-1, [Milestone(-1, [Milestone(-5), Milestone(-10)]), Milestone(-3, [Milestone(-7)])]).

A
class Milestone(object):
    def \_\_init\_\_(self, points, children = None):
        self.points = points
        self.children = children or []
    
# game = Milestone(-1, [Milestone(-1, [Milestone(-5), Milestone(-10)]), Milestone(-3, [Milestone(-7)])]) #expect -7
game = Milestone(1, [Milestone(1, [Milestone(5), Milestone(10)]), Milestone(3, [Milestone(7)])]) #expect 12.

def find_max_points(game):
    def dfs(root, curSum):
        if not root:
            return 0
        curSum += root.points
        
        if not root.children:
            return curSum
        
        res = -float('inf')
        for child in root.children:
            res = max(dfs(child, curSum), res)
        return res
    return dfs(game, 0)

print(find_max_points(game))
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Find repetitions in paragraph

A
paragraph = "The hello world. The is the world hello!"
#World: 2 occurrences -> 1 repetition
#The: 3 occurrences -> 2 repetitions
#hello: 2 occurrences -> 1 repetition

import re
def find_repetitions(paragraph):
    #\W matches any non-word character (equivalent to [^a-zA-Z0-9_])
    paragraph = re.sub("\W", " ", paragraph).lower()
    wordList = paragraph.split()
    wordToCount = {}
    
    res = 0
    for w in wordList:
        wordToCount[w] = wordToCount.get(w, 0) + 1
    print(wordToCount)
    for w in wordToCount:
        res += wordToCount[w] - 1
    return res
print(find_repetitions(paragraph))
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

How to turn paragraph into lower case, no punctuations, and stripped of spaces? Then get all the words.

A

import re
paragraph = re.sub(“\W”, “ “, paragraph).lower()
#\W matches any non-word character (equivalent to [^a-zA-Z0-9_])
words = paragraph.split()
print(words

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Determine the triangle type. Scalene, Isosceles, Equilateral. Valid triangle if sum of two sides’ lengths >= third.

A
def getTriangleType(lengths):
    a, b, c = lengths
    if a + b <= c or a + c <= b or b + c <= a:
        return "Not a Triangle"
    lengthSet = set(lengths)
    if len(lengthSet) == 3:
        return "Scalene"
    elif len(lengthSet) == 2:
        return "Isosceles"
    else:
        return "Equilateral"
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Given a stream of blah | blah | tags, perform single and multi-tag search to return all the associated tags with a particular user_input of tags.
Example:
stream = [
“blah|blah|host:a,role:web,region:us-east-1a”,
“blah|blah|host:b,role:web,region:us-east-1b”,
“blah3|blah3|host:a,role:web,region:us-east-1a”,
“blah2|blah2|host:c,role:db,db_role:primary,region:us-east-1e”
]
user_input = [“role:web”] #Expected: {‘host:b’, ‘region:us-east-1a’, ‘region:us-east-1b’, ‘host:a’}
user_input = [“role:db”, “db_role:primary”] #Expected: {‘region:us-east-1e’, ‘host:c’}
user_input = [“host:a”, “host:b”] #Expected: {}

A
"""
#High-level design is a Hashmap:
#Key: the individual Tag
#Value: set of tag lines that contain the individual tag in full

#So to do multi-tag search:
#We get the sets of tag lines, one set for each multitag
#Perform an intersection of those sets to find the common tag line
#Then finally, iterate through this tag line and take everything that is NOT in the multi-tag search. Set difference?

For example:
hosta: set("blah|blah|host:a, role:web, region:us-east-1a", "blah|blah|host:a, role:web, region:us-east-1a")
hostb: set("blah|blah|host:b, role:web, region:us-east-1b")
roledb: set("host:c, role:db, db_role:primary, region:us-east-1e")
dbrole:primary: set(host:c, role:db, db_role:primary, region:us-east-1e)

"""
stream = [
    "blah|blah|host:a,role:web,region:us-east-1a",
    "blah|blah|host:b,role:web,region:us-east-1b",
    "blah3|blah3|host:a,role:web,region:us-east-1a",
    "blah2|blah2|host:c,role:db,db_role:primary,region:us-east-1e"
]
from collections import defaultdict
tagsMap = defaultdict(set)
def populateTagsMap(stream):
    for line in stream:
        tagsLine = line.split("|")[-1]
        allTags = tagsLine.split(",")
        #print(allTags)
        for tag in allTags:
            tagsMap[tag].add(tagsLine)

def getAssociatedTags(userInput):
    commonLinesSet = tagsMap[userInput[0]]
    
    
    if len(userInput) > 1:
        for tag in userInput[1:]:
            commonLinesSet = commonLinesSet.intersection(tagsMap[tag])
    
    collapsedSet = set()
    for line in commonLinesSet:
        tags = line.split(",")
        for tag in tags:
            collapsedSet.add(tag)
    remainingTags = collapsedSet.difference(set(userInput))
    print(remainingTags)
    return remainingTags
    
user_input = ["role:web"] #Expected: {'host:b', 'region:us-east-1a', 'region:us-east-1b', 'host:a'}
user_input = ["role:db", "db_role:primary"] #Expected: {'region:us-east-1e', 'host:c'}
user_input = ["host:a", "host:b"] #Expected: {}

populateTagsMap(stream)
# print(getAssociatedTags(user_input))
getAssociatedTags(user_input) 
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Path Sum II
Given the root of a binary tree and an integer targetSum, return all root-to-leaf paths where the sum of the node values in the path equals targetSum. Each path should be returned as a list of the node values, not node references.

A root-to-leaf path is a path starting from the root and ending at any leaf node. A leaf is a node with no children.
Input: root = [5,4,8,11,null,13,4,7,2,null,null,5,1], targetSum = 22
Output: [[5,4,11,2],[5,8,4,5]]
Explanation: There are two paths whose sum equals targetSum:
5 + 4 + 11 + 2 = 22
5 + 8 + 4 + 5 = 22

A
# Definition for a binary tree node.
# class TreeNode:
#     def \_\_init\_\_(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def pathSum(self, root: Optional[TreeNode], targetSum: int) -> List[List[int]]:
        res = []
        def dfs(node, curSum, curPath):
            if not node:
                return
            
            curSum += node.val
            if not node.left and not node.right:
                if curSum == targetSum:
                    newPath = curPath + [node.val]
                    res.append(newPath)
            
            dfs(node.left, curSum, curPath + [node.val])
            dfs(node.right, curSum, curPath + [node.val])
        dfs(root, 0, [])
        return res
        #O(n)
        #O(h)

            
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Largest Odd Number in String

You are given a string num, representing a large integer. Return the largest-valued odd integer (as a string) that is a non-empty substring of num, or an empty string “” if no odd integer exists.

A substring is a contiguous sequence of characters within a string.

Input: num = “52”
Output: “5”
Explanation: The only non-empty substrings are “5”, “2”, and “52”. “5” is the only odd number.

A
class Solution:
    def largestOddNumber(self, num: str) -> str:
        for i in range(len(num) - 1, -1, -1):
            if int(num[i]) % 2:
                return num[: i + 1]
        return ""
        #O(n)
        #O(1)
17
Q
A