Skip to main content

Painting a Grid With Three Different Colors - Solution & Explanation

HardDynamic Programming24 min readAsked at: Amazon, Microsoft, Meta +4
Practice this problem

Problem Statement

You are given two integers m and n. Consider an m x n grid where each cell is initially white. You can paint each cell red, green, or blue. All cells must be painted.

Return the number of ways to color the grid with no two adjacent cells having the same color. Since the answer can be very large, return it modulo 109 + 7.

 

Example 1:

Input: m = 1, n = 1
Output: 3
Explanation: The three possible colorings are shown in the image above.

Example 2:

Input: m = 1, n = 2
Output: 6
Explanation: The six possible colorings are shown in the image above.

Example 3:

Input: m = 5, n = 5
Output: 580986

 

Constraints:

  • 1 <= m <= 5
  • 1 <= n <= 1000

Approach Overview

Problem Overview: You need to paint an m x n grid using three colors so that no two adjacent cells share the same color. Adjacent means both vertical and horizontal neighbors. The goal is to count the number of valid colorings modulo 1e9 + 7.

Approach 1: Dynamic Programming with Pattern Compression (O(n * S^2) time, O(S) space)

The key observation: constraints only depend on neighboring columns. Instead of tracking every cell, compress each column into a state. A state represents a valid coloring of one column where vertically adjacent cells have different colors. For m ≤ 5, there are at most 3^m possibilities, and only the ones with no vertical conflicts are kept. Precompute all valid column states, then build a compatibility graph where two states can follow each other if every row has different colors across the columns.

Dynamic programming runs column by column. Let dp[i][state] be the number of ways to paint up to column i ending with that column pattern. For each new column, iterate through compatible previous states and accumulate counts. Because the number of valid states is small (around 48 when m = 5), the transition cost stays manageable. This is a classic column-compression technique often used in dynamic programming and bitmask DP style problems.

Approach 2: Optimized Dynamic Programming with Memoization (O(n * S^2) time, O(n * S) space)

This variation uses top‑down recursion with memoization. First generate all valid column patterns exactly like the compression approach. Then recursively compute the number of ways to fill columns starting from index 0. The state is defined by (columnIndex, previousPattern). For each step, iterate through all patterns that are compatible with the previous one and recursively process the next column.

Memoization avoids recomputing overlapping subproblems. The recursion depth equals n, and each state explores only valid transitions between patterns. This approach is easier to reason about because it models the grid as a sequence of column decisions, while still leveraging the same compressed state space.

Recommended for interviews: Pattern compression with bottom‑up DP is the expected solution. It shows you can reduce a 2D coloring problem into manageable column states and precompute transitions. Mentioning the brute 3^(m*n) search briefly demonstrates why compression is necessary, but implementing the optimized DP proves strong dynamic programming skills and awareness of state reduction techniques.

Approach 1: Dynamic Programming with Pattern Compression

We will use dynamic programming to solve this problem by first focusing on a single column. Each column can have certain valid color patterns that adhere to the rules -- no two adjacent cells have the same color. We will precompute these valid patterns and then extend this to multiple columns using dynamic programming.

The core idea is to calculate the number of ways to fill the grid up to each column, given the pattern of the previous column. This involves considering all possible compatible patterns for new columns based on previous ones. We store results in a DP table and utilize modulo operations to avoid overflow.

This C code calculates the number of ways to color the grid using dynamic programming. The two variables 'color3' and 'color2' store the number of ways to paint a column in a 3-color pattern and a 2-color pattern respectively. The loops iterate over columns and update these patterns based on previous columns, respecting the color rules.

Code

C

C++

Java

Python

C#

JavaScript

Complexity

The time complexity is O(n), and the space complexity is O(1) as we only use a fixed amount of extra space.

Try this approach in the editor →

Approach 2: Optimized Dynamic Programming with Memoization

This method involves using a memoization table to record transitions between valid patterns. The key is to represent each valid column configuration in a way that captures all legal states, and keep track of transitions between states to avoid redundant calculations. This dramatically reduces the computation complexities by caching evaluations.

By using bitwise operations or effectively encoding states, patterns can be compactly stored, leveraging recursion with memoization to efficiently compute the total number of colorings.

In this C solution, a recursive function is used, coupled with a memoization table (a 2-dimensional array) to store previous results. The 'isValidState' function checks if a particular configuration complies with color rules.

Code

C

C++

Java

Python

C#

JavaScript

Complexity

Space and time complexities can be near O(n * 3^m) due to memoization and reduced redundant calculations.

Try this approach in the editor →

Approach 3: State Compression + Dynamic Programming

We notice that the number of rows in the grid does not exceed 5, so there are at most 3^5=243 different color schemes in a column.

Therefore, we define f[i][j] to represent the number of schemes in the first i columns, where the coloring state of the ith column is j. The state f[i][j] is transferred from f[i - 1][k], where k is the coloring state of the i - 1th column, and k and j meet the requirement of different colors being adjacent. That is:

$ f[i][j] = sum_{k \in valid(j)} f[i - 1][k]

where valid(j) represents all legal predecessor states of state j.

The final answer is the sum of f[n][j], where j is any legal state.

We notice that f[i][j] is only related to f[i - 1][k], so we can use a rolling array to optimize the space complexity.

The time complexity is O((m + n) times 3^{2m}), and the space complexity is O(3^m). Here, m and n$ are the number of rows and columns of the grid, respectively.

Code

Python

Java

C++

Go

TypeScript

Try this approach in the editor →

Complexity Comparison

ApproachComplexity
Dynamic Programming with Pattern Compression

The time complexity is O(n), and the space complexity is O(1) as we only use a fixed amount of extra space.

Optimized Dynamic Programming with Memoization

Space and time complexities can be near O(n * 3^m) due to memoization and reduced redundant calculations.

State Compression + Dynamic Programming

Detailed Complexity Analysis

ApproachTimeSpaceWhen to Use
Dynamic Programming with Pattern CompressionO(n * S^2)O(S)Best practical approach when rows are small (m ≤ 5) and columns are large
Optimized DP with MemoizationO(n * S^2)O(n * S)When recursion is easier to implement and you want clearer state transitions

Video Solution

Painting a Grid With Three Different Colors | Thought Process | Leetcode 1931 | codestorywithMIKcodestorywithMIK17,639 views views

Watch 9 more video solutions →

Frequently Asked Questions

Is Painting a Grid With Three Different Colors easy or hard?
Painting a Grid With Three Different Colors is classified as Hard because the naive search space is exponential. The challenge is recognizing that the grid can be processed column by column and compressed into a small set of valid states using dynamic programming.
Painting a Grid With Three Different Colors Python/Java solution
Python and Java implementations typically generate all valid column states using DFS or base-3 enumeration, precompute compatible transitions, then run dynamic programming across columns. Python uses lists and dictionaries for state transitions, while Java often uses arrays for faster DP updates.
How to solve Painting a Grid With Three Different Colors in O(n)?
Pure O(n) time is not achievable because each column must check transitions with multiple valid patterns. The closest efficient approach is O(n * S^2) using pattern-compressed dynamic programming, where S is small due to the constraint m ≤ 5. This keeps the algorithm fast even for n up to 1000.
What is the best approach for Painting a Grid With Three Different Colors?
The most efficient approach uses pattern compression with dynamic programming. Each column is represented as a valid color pattern where vertically adjacent cells differ. Precompute all valid patterns and transitions between compatible columns, then run DP across columns. This reduces the problem from 3^(m*n) possibilities to roughly O(n * S^2) where S is the number of valid column states.
Is Painting a Grid With Three Different Colors asked at Google/Amazon/Meta?
Grid coloring and state-compression dynamic programming problems appear frequently in interviews at companies like Google and Meta. Variants involving column DP, tiling, or bitmask state transitions are common in high-difficulty interview rounds.
What data structure is used in Painting a Grid With Three Different Colors?
The solution mainly uses arrays or hash maps for dynamic programming states and lists to store valid column patterns. Many implementations encode patterns using integers or base-3 representations, similar to techniques used in bitmask dynamic programming.
What is the time complexity of Painting a Grid With Three Different Colors?
The optimized dynamic programming solution runs in O(n * S^2) time, where S is the number of valid column patterns (about 48 when m = 5). Space complexity is O(S) for the iterative DP version or O(n * S) for memoized recursion.

Ready to solve this problem?

Practice Painting a Grid With Three Different Colors with our built-in code editor and test cases.

Practice on FleetCode