Welcome to Subscribe On Youtube

Formatted question description: https://leetcode.ca/all/1591.html

1591. Strange Printer II (Hard)

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.

Example 4:

Input: targetGrid = [[1,1,1],[3,1,3]]
Output: false

 

Constraints:

  • m == targetGrid.length
  • n == targetGrid[i].length
  • 1 <= m, n <= 60
  • 1 <= targetGrid[row][col] <= 60

Related Topics:
Greedy

Similar Questions:

Solution 1.

  • class Solution {
        public boolean isPrintable(int[][] targetGrid) {
            Map<Integer, int[]> boundsMap = new HashMap<Integer, int[]>();
            int rows = targetGrid.length, columns = targetGrid[0].length;
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < columns; j++) {
                    int color = targetGrid[i][j];
                    if (!boundsMap.containsKey(color))
                        boundsMap.put(color, new int[]{i, i, j, j});
                    else {
                        int[] bounds = boundsMap.get(color);
                        bounds[0] = Math.min(bounds[0], i);
                        bounds[1] = Math.max(bounds[1], i);
                        bounds[2] = Math.min(bounds[2], j);
                        bounds[3] = Math.max(bounds[3], j);
                        boundsMap.put(color, bounds);
                    }
                }
            }
            Set<Integer> keySet = boundsMap.keySet();
            Map<Integer, List<Integer>> greaterMap = new HashMap<Integer, List<Integer>>();
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < columns; j++) {
                    int color = targetGrid[i][j];
                    List<Integer> list = greaterMap.getOrDefault(color, new ArrayList<Integer>());
                    for (int key : keySet) {
                        if (key != color) {
                            int[] bounds = boundsMap.get(key);
                            if (i >= bounds[0] && i <= bounds[1] && j >= bounds[2] && j <= bounds[3])
                                list.add(key);
                        }
                    }
                    greaterMap.put(color, list);
                }
            }
            Map<Integer, Integer> indegreeMap = new HashMap<Integer, Integer>();
            for (int color : keySet) {
                List<Integer> nextColors = greaterMap.getOrDefault(color, new ArrayList<Integer>());
                for (int nextColor : nextColors) {
                    int indegree = indegreeMap.getOrDefault(nextColor, 0) + 1;
                    indegreeMap.put(nextColor, indegree);
                }
            }
            Set<Integer> visited = new HashSet<Integer>();
            Queue<Integer> queue = new LinkedList<Integer>();
            for (int color : keySet) {
                int indegree = indegreeMap.getOrDefault(color, 0);
                if (indegree == 0) {
                    visited.add(color);
                    queue.offer(color);
                }
            }
            while (!queue.isEmpty()) {
                int color = queue.poll();
                List<Integer> nextColors = greaterMap.getOrDefault(color, new ArrayList<Integer>());
                for (int nextColor : nextColors) {
                    int indegree = indegreeMap.getOrDefault(nextColor, 0) - 1;
                    if (indegree == 0) {
                        indegreeMap.remove(nextColor);
                        visited.add(nextColor);
                        queue.offer(nextColor);
                    } else
                        indegreeMap.put(nextColor, indegree);
                }
            }
            return visited.size() == keySet.size();
        }
    }
    
  • // OJ: https://leetcode.com/problems/strange-printer-ii/
    // Time: O(C^2 * MN)
    // Space: O(MN)
    class Solution {
        bool removable(vector<vector<int>> &G, vector<vector<int>> &pos, int c) {
            for (int i = pos[c][0]; i <= pos[c][2]; ++i) {
                for (int j = pos[c][1]; j <= pos[c][3]; ++j) {
                    if (G[i][j] != c && G[i][j] != 0) return false;
                }
            }
            for (int i = pos[c][0]; i <= pos[c][2]; ++i) {
                for (int j = pos[c][1]; j <= pos[c][3]; ++j) G[i][j] = 0;
            }
            return true;
        }
    public:
        bool isPrintable(vector<vector<int>>& G) {
            int M = G.size(), N = G[0].size();
            vector<vector<int>> pos(61, {M, N, 0, 0});
            unordered_set<int> colors, remove;
            for (int i = 0; i < M; ++i) {
                for (int j = 0; j < N; ++j) {
                    int c = G[i][j];
                    colors.insert(c);
                    pos[c][0] = min(pos[c][0], i);
                    pos[c][1] = min(pos[c][1], j);
                    pos[c][2] = max(pos[c][2], i);
                    pos[c][3] = max(pos[c][3], j);
                }
            }
            while (colors.size()) {
                for (int c : colors) {
                    if (removable(G, pos, c)) remove.insert(c);
                }
                if (remove.empty()) return false;
                for (int c : remove) colors.erase(c);
                remove.clear();
            }
            return true;
        }
    };
    

All Problems

All Solutions