You are stacking blocks to form a pyramid. Each block has a color, which is represented by a single letter. Each row of blocks contains one less block than the row beneath it and is centered on top.
To make the pyramid aesthetically pleasing, there are only specific triangular patterns that are allowed. A triangular pattern consists of a single block stacked on top of two blocks. The patterns are given as a list of three-letter strings allowed, where the first two characters of a pattern represent the left and right bottom blocks respectively, and the third character is the top block.
"ABC" represents a triangular pattern with a 'C' block stacked on top of an 'A' (left) and 'B' (right) block. Note that this is different from "BAC" where 'B' is on the left bottom and 'A' is on the right bottom.You start with a bottom row of blocks bottom, given as a single string, that you must use as the base of the pyramid.
Given bottom and allowed, return true if you can build the pyramid all the way to the top such that every triangular pattern in the pyramid is in allowed, or false otherwise.
Example 1:
Input: bottom = "BCD", allowed = ["BCC","CDE","CEA","FFF"] Output: true Explanation: The allowed triangular patterns are shown on the right. Starting from the bottom (level 3), we can build "CE" on level 2 and then build "A" on level 1. There are three triangular patterns in the pyramid, which are "BCC", "CDE", and "CEA". All are allowed.
Example 2:
Input: bottom = "AAAA", allowed = ["AAB","AAC","BCD","BBE","DEF"] Output: false Explanation: The allowed triangular patterns are shown on the right. Starting from the bottom (level 4), there are multiple ways to build level 3, but trying all the possibilites, you will get always stuck before building level 1.
Constraints:
2 <= bottom.length <= 60 <= allowed.length <= 216allowed[i].length == 3{'A', 'B', 'C', 'D', 'E', 'F'}.allowed are unique.When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The pyramid transition problem asks if we can build a pyramid from a given bottom string, using allowed three-character building blocks. Brute force means we'll explore every single possible pyramid construction, trying all combinations until we find one that works, or exhaust all options.
Here's how the algorithm would work step-by-step:
def pyramid_transition(bottom, allowed):
allowed_transitions = {}
for transition in allowed:
base = transition[:2]
top = transition[2]
if base not in allowed_transitions:
allowed_transitions[base] = set()
allowed_transitions[base].add(top)
def can_build_pyramid(current_level):
if len(current_level) == 1:
return True
next_level_possibilities = []
for i in range(len(current_level) - 1):
pair = current_level[i:i+2]
# If the pair isn't in allowed, then no further searching needed
if pair not in allowed_transitions:
return False
if not next_level_possibilities:
for character in allowed_transitions[pair]:
next_level_possibilities.append(character)
else:
new_possibilities = []
for character in allowed_transitions[pair]:
for existing_level in next_level_possibilities:
new_possibilities.append(existing_level + character)
next_level_possibilities = new_possibilities
# Iterate through all possibilities for the next level
for next_level in next_level_possibilities:
if can_build_pyramid(next_level):
return True
# If all next levels failed, then return False
return False
return can_build_pyramid(bottom)The most efficient way to solve this problem is to figure out what blocks can be built on top of other blocks. Instead of exploring every possible pyramid, we pre-compute which combinations of blocks are allowed and then use this knowledge to check if we can build the pyramid one level at a time, starting from the base.
Here's how the algorithm would work step-by-step:
def pyramidTransition(bottom, allowed):
allowed_combinations = {}
for combination in allowed:
base = combination[:2]
top = combination[2]
if base not in allowed_combinations:
allowed_combinations[base] = set()
allowed_combinations[base].add(top)
def canBuild(current_level):
if len(current_level) == 1:
return True
next_level_possibilities = []
for i in range(len(current_level) - 1):
pair = current_level[i:i+2]
if pair in allowed_combinations:
next_level_possibilities.append(allowed_combinations[pair])
else:
return False
# Need to explore different combinations for the next level
def generateNextLevel(index, current_next_level):
if index == len(next_level_possibilities):
return canBuild("".join(current_next_level))
for possible_block in next_level_possibilities[index]:
if generateNextLevel(index + 1, current_next_level + [possible_block]):
return True
return False
# Begin building the next level recursively
return generateNextLevel(0, [])
# Check if the bottom level can build the pyramid
return canBuild(bottom)| Case | How to Handle |
|---|---|
| Null or empty bottom string | Return True if an empty string is provided as the bottom, as it vacuously satisfies the condition; otherwise, handle the null case with an appropriate error, such as raising an IllegalArgumentException. |
| Empty allowed list | If the allowed list is empty, and the bottom string is not empty, it is impossible to build a valid pyramid so return False. |
| Bottom string length is 1 | If the bottom string has length 1, the pyramid is trivially valid only if the allowed characters permit creating a level above it which could be one character long, handled within the recursive valid pyramid construction. |
| Maximum string length exceeding practical recursion depth | Consider memoization or dynamic programming to avoid excessive recursion depth and potential stack overflow errors for long strings. |
| Allowed list contains duplicate triplets | The algorithm should treat duplicates in the allowed list as the same allowed transition, and it will not negatively affect the generation of the pyramid. |
| No valid pyramid exists for the given bottom and allowed | The solution should correctly return False when there's no possible pyramid based on the bottom string and allowed transitions by exhaustively checking all possibilities. |
| Integer overflow in calculating indices, if any indices calculation exists | Use appropriate data types or modular arithmetic to prevent integer overflow when calculating indices based on string length or positions. |
| Allowed string characters are not consistent with bottom string characters | Validate that all characters in the bottom string are present in the allowed transitions to prevent errors, returning False if invalid characters are present. |