You have a grid of size n x 3 and you want to paint each cell of the grid with exactly one of the three colors: Red, Yellow, or Green while making sure that no two adjacent cells have the same color (i.e., no two cells that share vertical or horizontal sides have the same color).
Given n the number of rows of the grid, return the number of ways you can paint this grid. As the answer may grow large, the answer must be computed modulo 109 + 7.
Example 1:
Input: n = 1 Output: 12 Explanation: There are 12 possible way to paint the grid as shown.
Example 2:
Input: n = 5000 Output: 30228214
Constraints:
n == grid.length1 <= n <= 5000When 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:
Every row is colored by trying all three colors in each of the three cells. A coloring is rejected when two cells that share a side have the same color, including a cell that matches the cell directly above it. Completed colorings of all n rows are counted, with no stored answers and no modulus.
Here's how the algorithm would work step-by-step:
class Solution:
def numOfWays(self, grid_height: int) -> int:
# Represents Red, Green, Blue
colors = [0, 1, 2]
total_valid_ways = 0
def generate_and_count(row_index, previous_row_colors):
nonlocal total_valid_ways
# This is the base case: if we have successfully painted all rows, we found one valid way.
if row_index == grid_height:
total_valid_ways += 1
return
# Explore all possible color combinations for the current row.
for first_color in colors:
for second_color in colors:
for third_color in colors:
# A valid row cannot have adjacent cells with the same color.
if first_color == second_color or second_color == third_color:
continue
current_row_colors = [first_color, second_color, third_color]
# For the first row, any valid coloring is acceptable as there's no row above it.
if row_index == 0:
generate_and_count(row_index + 1, current_row_colors)
else:
is_coloring_valid_with_previous = True
for column_index in range(3):
if current_row_colors[column_index] == previous_row_colors[column_index]:
is_coloring_valid_with_previous = False
break
# If the current row's coloring is valid with respect to the previous row, proceed.
if is_coloring_valid_with_previous:
generate_and_count(row_index + 1, current_row_colors)
generate_and_count(0, None)
return total_valid_waysValid rows fall into two families: rows whose ends match, and rows whose three colors are all different. There are six rows in each family on the first row. Each later row is counted from the previous two family sizes with a fixed linear combination, and every count is reduced modulo 1,000,000,007.
Here's how the algorithm would work step-by-step:
class Solution:
def numOfWays(self, number_of_rows: int) -> int:
MOD = 10**9 + 7
# Initialize counts for the first row (n=1) based on the two pattern types.
# Type 1 (ABA): 3 choices for A, 2 choices for B. Total = 3 * 2 = 6.
# Type 2 (ABC): 3 choices for A, 2 for B, 1 for C. Total = 3 * 2 * 1 = 6.
rows_with_same_ends_count = 6
rows_with_diff_ends_count = 6
# Build up the counts for each subsequent row using the totals from the previous row.
for _ in range(2, number_of_rows + 1):
# A pattern with the same ends (e.g., ABA) can be formed from:
# - A previous row with same ends (XYX) in 3 ways (e.g., YXY, YZY, ZYZ).
# - A previous row with diff ends (XYZ) in 2 ways (e.g., YXY, ZXZ).
next_rows_with_same_ends = (rows_with_same_ends_count * 3 + rows_with_diff_ends_count * 2) % MOD
# A pattern with different ends (e.g., ABC) can be formed from:
# - A previous row with same ends (XYX) in 2 ways (e.g., YZA, ZYA).
# - A previous row with diff ends (XYZ) in 2 ways (e.g., YZA, ZXY).
next_rows_with_diff_ends = (rows_with_same_ends_count * 2 + rows_with_diff_ends_count * 2) % MOD
rows_with_same_ends_count = next_rows_with_same_ends
rows_with_diff_ends_count = next_rows_with_diff_ends
total_ways = (rows_with_same_ends_count + rows_with_diff_ends_count) % MOD
return total_ways| Case | How to Handle |
|---|---|
| The grid has a single row | Both versions return twelve, the number of colorings whose side-by-side cells differ. |
| A row uses the same color on two cells that share a side | That row is rejected. |
| A row matches the row above in even one column | That coloring is rejected. |
| The first and third cells of a row use the same color | The row is still allowed when the middle cell uses a different color. |
| The grid is tall | The fast count is reduced modulo 1,000,000,007, while the exhaustive count is the raw total. |