LeetCode #1284 Minimum Number of

2022-08-29  本文已影响0人  air_melt

1284 Minimum Number of Flips to Convert Binary Matrix to Zero Matrix 转化为全零矩阵的最少反转次数

Description:

Given a m x n binary matrix mat. In one step, you can choose one cell and flip it and all the four neighbors of it if they exist (Flip is changing 1 to 0 and 0 to 1). A pair of cells are called neighbors if they share one edge.

Return the minimum number of steps required to convert mat to a zero matrix or -1 if you cannot.

A binary matrix is a matrix with all cells equal to 0 or 1 only.

A zero matrix is a matrix with all cells equal to 0.

Example:

Example 1:

[图片上传失败...(image-96ef52-1661785486992)]

Input: mat = [[0,0],[0,1]]
Output: 3
Explanation: One possible solution is to flip (1, 0) then (0, 1) and finally (1, 1) as shown.

Example 2:

Input: mat = [[0]]
Output: 0
Explanation: Given matrix is a zero matrix. We do not need to change it.

Example 3:

Input: mat = [[1,0,0],[1,0,0]]
Output: -1
Explanation: Given matrix cannot be a zero matrix.

Constraints:

m == mat.length
n == mat[i].length
1 <= m, n <= 3
mat[i][j] is either 0 or 1.

题目描述:

给你一个 m x n 的二进制矩阵 mat。每一步,你可以选择一个单元格并将它反转(反转表示 0 变 1 ,1 变 0 )。如果存在和它相邻的单元格,那么这些相邻的单元格也会被反转。相邻的两个单元格共享同一条边。

请你返回将矩阵 mat 转化为全零矩阵的最少反转次数,如果无法转化为全零矩阵,请返回 -1 。

二进制矩阵 的每一个格子要么是 0 要么是 1 。

全零矩阵 是所有格子都为 0 的矩阵。

示例:

示例 1:

[图片上传失败...(image-2110c2-1661785486992)]

输入:mat = [[0,0],[0,1]]
输出:3
解释:一个可能的解是反转 (1, 0),然后 (0, 1) ,最后是 (1, 1) 。

示例 2:

输入:mat = [[0]]
输出:0
解释:给出的矩阵是全零矩阵,所以你不需要改变它。

示例 3:

输入:mat = [[1,0,0],[1,0,0]]
输出:-1
解释:该矩阵无法转变成全零矩阵

提示:

m == mat.length
n == mat[0].length
1 <= m <= 3
1 <= n <= 3
mat[i][j] 是 0 或 1 。

思路:

DFS ➕ 状态压缩
对每一格都有翻转或者不翻转两种选择
遍历所有格子, 每个格子都尝试两种选择, 记录下到达终点时数组全部为 0 的翻转次数
时间复杂度为 O(mn2 ^ mn), 空间复杂度为 O(mn)

代码:

C++:

class Solution 
{
private:
    vector<vector<int>> dirs{{0, 0}, {0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    int m, n;
    
    void flip(vector<vector<int>>& mat, int x, int y)
    {
        for (const auto& dir : dirs) if (x + dir.front() > -1 and x + dir.front() < m and y + dir.back() > -1 and y + dir.back() < n) mat[x + dir.front()][y + dir.back()] ^= 1;
    }
    
    int dfs(vector<vector<int>>& mat, int state)
    {
        if (state == m * n) 
        {
            int cur = 0;
            for (const auto& row : mat) cur += accumulate(row.begin(), row.end(), 0);
            return cur ? 0x3f3f3f3f : 0;
        }
        int x = state / n, y = state % n, record = dfs(mat, state + 1);
        flip(mat, x, y);
        record = min(record, dfs(mat, state + 1) + 1);
        flip(mat, x, y);
        return record;
    }
public:
    int minFlips(vector<vector<int>>& mat) 
    {
        m = mat.size();
        n = mat.front().size();
        int result = dfs(mat, 0);
        return result < 0x3f3f3f3f ? result : -1;
    }
};

Java:

class Solution {
    private int m, n, dirs[][] = new int[][]{{0, 0}, {0, 1}, {0, -1}, {1, 0}, {-1, 0}};
    public int minFlips(int[][] mat) {
        m = mat.length;
        n = mat[0].length;
        int result = dfs(mat, 0);
        return result < 0x3f3f3f3f ? result : -1;
    }
    
    private void flip(int[][] mat, int x, int y) {
        for (int[] dir : dirs) if (x + dir[0] > -1 && x + dir[0] < m && y + dir[1] > -1 && y + dir[1] < n) mat[x + dir[0]][y + dir[1]] ^= 1;
    }
    
    private int dfs(int[][] mat, int state) {
        if (state == m * n) {
            int cur = 0;
            for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) cur += mat[i][j];
            if (cur == 0) return cur;
            return 0x3f3f3f3f;
        }
        int x = state / n, y = state % n, record = dfs(mat, state + 1);
        flip(mat, x, y);
        record = Math.min(dfs(mat, state + 1) + 1, record);
        flip(mat, x, y);
        return record;
    }
}

Python:

class Solution:
    def minFlips(self, mat: List[List[int]]) -> int:
        def flip(x: int, y: int) -> None:
            for dx, dy in d:
                if -1 < x + dx < m and -1 < y + dy < n:
                    mat[x + dx][y + dy] ^= 1
            
        def dfs(state: int) -> int:
            if state == m * n:
                return 0 if not sum(sum(i) for i in mat) else float("inf")
            x, y = state // n, state % n
            record = dfs(state + 1)
            flip(x, y)
            record = min(record, 1 + dfs(state + 1))
            flip(x, y)
            return record

        m, n, d = len(mat), len(mat[0]), [(0, 0), (0, 1), (0, -1), (1, 0), (-1, 0)]
        return result if (result := dfs(0)) < float("inf") else -1
上一篇下一篇

猜你喜欢

热点阅读