【狀壓 dp】A000_LC_轉化爲全零矩陣的最少反轉次數(回溯 / dp / bfs)

一、Problem

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

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

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

Zero matrix is a matrix with all cells equal to 0.
在這裏插入圖片描述

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.

二、Solution

方法一:回溯

  • 結束條件
    • 當矩陣出現全 0 時,結算最小操作次數 min 並返回。
    • 當把所有位置都翻轉了一遍後,也返回。
  • 本層遞歸的責任:對於當前格子,可選擇翻轉或不翻轉:
    • 選擇翻轉,那麼四周的格子也需要翻轉。
    • 否則,下一輪選擇。

這裏的換行技巧要熟練…

class Solution {
	int tot, R, C, min = Integer.MAX_VALUE, g[][];
	final static int[][] d = { {1,0},{0,-1},{0,1},{-1,0} };
	void dfs(int x, int y, int s) {
		boolean allZero = true;
		loop:
		for (int i = 0; i < R; i++)
		for (int j = 0; j < C; j++) {
			if (g[i][j] != 0) {
				allZero = false;
				break loop;
			}
		}
		if (allZero) {
			min = Math.min(min, s);
			return;
		}
		
		int nx = x, ny = y + 1;
		if (ny >= C) {
			nx++;
			ny = 0;
		}
        if (nx >= R)
            return;
		dfs(nx, ny, s);
		g[nx][ny] ^= 1;
		for (int k = 0; k < 4; k++) {
			int tx = nx + d[k][0], ty = ny + d[k][1];
			if (tx < 0 || tx >= R || ty < 0 || ty >= C)
				continue;
			g[tx][ty] ^= 1;
		}
		dfs(nx, ny, s+1);
		g[nx][ny] ^= 1;
		for (int k = 0; k < 4; k++) {
			int tx = nx + d[k][0], ty = ny + d[k][1];
			if (tx < 0 || tx >= R || ty < 0 || ty >= C)
				continue;
			g[tx][ty] ^= 1;
		}
	}
	public int minFlips(int[][] mat) {
		g = mat;
		R = g.length; C = g[0].length;
		dfs(0, -1, 0);
		return min == Integer.MAX_VALUE ? -1 : min;
	}
}

複雜度分析

  • 時間複雜度:O(R×C)O(R × C)
  • 空間複雜度:O(R×C)O(R × C)

方法二:dp

狀態壓縮,代辦…


複雜度分析

  • 時間複雜度:O()O()
  • 空間複雜度:O()O()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章