Advertisement
bennyfromtheblock

LC 691: Stickers to Spell Word

Dec 17th, 2023
878
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.10 KB | None | 0 0
  1. # BFS solution where state is the count of characters remaining.
  2.  
  3.  
  4. class Solution:
  5.     def minStickers(self, stickers: List[str], target: str) -> int:
  6.         chars_in_target = sorted(list(set(list(target))))
  7.         char_to_idx = {c : i for i, c in enumerate(chars_in_target)}
  8.         n_chars = len(chars_in_target)
  9.  
  10.         # Reduce word to target chars only, represent as ordered count of chars in target
  11.         # This creates hashable state representations that are efficient to operate on
  12.         def condense(word: str) -> Tuple:
  13.             count_arr = [0 for _ in range(n_chars)]
  14.             for c in word:
  15.                 if c not in chars_in_target:
  16.                     continue
  17.                 count_arr[char_to_idx[c]] += 1
  18.  
  19.             return tuple(count_arr)
  20.  
  21.         # subtract sticker char count from target char count
  22.         def subtract(leftover, sticker):
  23.             return tuple([max(0, leftover[i] - sticker[i]) for i in range(n_chars)])
  24.  
  25.         # get number of characters a sticker can contribute to the target
  26.         def intersect(a, b):
  27.             return sum([min(a_i, b_i) for a_i, b_i in zip(a, b)])
  28.  
  29.         processed_stickers = {condense(sticker) for sticker in stickers}
  30.         initial_leftover_count = condense(target)
  31.        
  32.         # (leftover char count: Tuple, stickers used: int)
  33.         visited = set()
  34.         queue = deque([(initial_leftover_count, 0)])
  35.         visited.add((initial_leftover_count))
  36.  
  37.         while queue:
  38.             leftover, stickers_used = queue.popleft()
  39.             if sum(leftover) == 0:
  40.                 return stickers_used
  41.             to_discard = []
  42.             for sticker in processed_stickers:
  43.                 if not intersect(leftover, sticker):
  44.                     to_discard.append(sticker)
  45.                     continue
  46.                 new_leftover = subtract(leftover, sticker)
  47.                 if new_leftover in visited:
  48.                     continue
  49.                 queue.append((new_leftover, stickers_used + 1))
  50.            
  51.             map(lambda s: processed_stickers.remove(s), to_discard)
  52.  
  53.         return -1
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement