Skip to main content

Command Palette

Search for a command to run...

Solving Leetcode Interviews in Seconds with AI: Strange Printer II

Updated
3 min read

Introduction

In this blog post, we will explore how to solve the LeetCode problem "1591" using AI. LeetCode is a popular platform for preparing for coding interviews, and with the help of AI tools like Chatmagic, we can generate solutions quickly and efficiently - helping you pass the interviews and get the job offer without having to study for months.

Problem Statement

There is a strange printer with the following two special requirements: On each turn, the printer will print a solid rectangular pattern of a single color on the grid. This will cover up the existing colors in the rectangle. Once the printer has used a color for the above operation, the same color cannot be used again. You are given a m x n matrix targetGrid, where targetGrid[row][col] is the color in the position (row, col) of the grid. Return true if it is possible to print the matrix targetGrid, otherwise, return false. Example 1: Input: targetGrid = [[1,1,1,1],[1,2,2,1],[1,2,2,1],[1,1,1,1]] Output: true Example 2: Input: targetGrid = [[1,1,1,1],[1,1,3,3],[1,1,3,4],[5,5,1,4]] Output: true Example 3: Input: targetGrid = [[1,2,1],[2,1,2],[1,2,1]] Output: false Explanation: It is impossible to form targetGrid because it is not allowed to print the same color in different turns. Constraints: m == targetGrid.length n == targetGrid[i].length 1 <= m, n <= 60 1 <= targetGrid[row][col] <= 60

Explanation

Here's a breakdown of the solution and the code:

  • High-Level Approach:

    • Dependency Graph: Model the printing process as a dependency graph. Each color is a node. An edge from color a to color b means color a must be printed after color b (because color b covers color a in some overlapping rectangle).
    • Rectangle Check: For each pair of distinct colors, determine if one color must be printed after the other. This is done by identifying the smallest rectangle containing all occurrences of the first color, and then checking if the second color exists within that rectangle.
    • Cycle Detection: Use topological sort to detect cycles in the dependency graph. If a cycle exists, it's impossible to print the grid as required. If no cycle exists, it's possible.
  • Complexity:

    • Runtime: O(m n C^2), where m is the number of rows, n is the number of columns, and C is the number of distinct colors (at most 60). Storage: O(C^2), where C is the number of distinct colors.

Code

    def isPrintable(targetGrid):
    m = len(targetGrid)
    n = len(targetGrid[0])
    colors = set()
    for i in range(m):
        for j in range(n):
            colors.add(targetGrid[i][j])
    colors = sorted(list(colors))
    num_colors = len(colors)

    graph = [[] for _ in range(num_colors)]
    in_degree = [0] * num_colors

    color_positions = {color: [] for color in colors}
    for i in range(m):
        for j in range(n):
            color_positions[targetGrid[i][j]].append((i, j))

    def overlaps(color1, color2):
        min_row1, max_row1 = m, -1
        min_col1, max_col1 = n, -1

        for row, col in color_positions[color1]:
            min_row1 = min(min_row1, row)
            max_row1 = max(max_row1, row)
            min_col1 = min(min_col1, col)
            max_col1 = max(max_col1, col)

        for row, col in color_positions[color2]:
            if min_row1 <= row <= max_row1 and min_col1 <= col <= max_col1:
                return True
        return False


    for i in range(num_colors):
        for j in range(num_colors):
            if i != j:
                color1 = colors[i]
                color2 = colors[j]

                min_row1, max_row1 = m, -1
                min_col1, max_col1 = n, -1

                for row, col in color_positions[color1]:
                    min_row1 = min(min_row1, row)
                    max_row1 = max(max_row1, row)
                    min_col1 = min(min_col1, col)
                    max_col1 = max(max_col1, col)

                need_edge = False
                for row in range(min_row1, max_row1 + 1):
                    for col in range(min_col1, max_col1 + 1):
                        if targetGrid[row][col] == color2:
                            need_edge = True
                            break
                    if need_edge:
                        break

                if need_edge:
                    graph[i].append(j)
                    in_degree[j] += 1

    queue = [i for i in range(num_colors) if in_degree[i] == 0]
    count = 0

    while queue:
        node = queue.pop(0)
        count += 1

        for neighbor in graph[node]:
            in_degree[neighbor] -= 1
            if in_degree[neighbor] == 0:
                queue.append(neighbor)

    return count == num_colors

More from this blog

C

Chatmagic blog

2894 posts