给定一个维度为N*M的二进制矩阵mat[][] ,任务是从给定的二进制矩阵中找到所需的最小翻转次数,以便不存在从左上角单元格到底部的任何路径-右单元格仅由0组成。
例子:
Input: mat[][] = {{0, 1, 0, 0}, {0, 1, 0, 0}, {0, 1, 0, 0}, {0, 0, 0, 0}}
Output: 1
Explanation:
Operation 1: Flipping the cell at (1, 0) modifies the given matrix to:
0 1 0 0
1 1 0 0
0 1 0 0
0 0 0 0
After the above operations, there doesn’t exists any path from the top-left cell (0, 0) to the bottom-right cell (3, 3) consisting of only 0s. Therefore, the total number of flips required is 1.
Input: mat[][] = {{0, 0, 0, 0}, {0, 0, 0, 0}}
Output: 2
方法:可以使用给定矩阵上的 DFS 遍历来解决给定的问题,并基于观察到最多只存在2 次节点翻转,因此不存在从左上角单元格到底部的任何路径 -右单元格仅由0组成。这个想法是执行从左上角单元格到右下角单元格的 DFS 遍历,最多翻转一条路径,并打印成功的 DFS 调用次数作为结果。请按照以下步骤解决问题:
- 初始化一个函数,比如DFS(mat, i, j, N, M) ,它以当前单元格、给定矩阵及其大小为参数,并执行以下步骤:
- 如果当前单元格到达单元格(N – 1, M – 1)则返回true 。
- 将(i, j)处单元格的值更新为1 。
- 在当前单元格的所有四个方向递归调用 DFS函数,即(i + 1, j) 、 (i, j + 1) 、 (i – 1, j)和(i, j – 1)如果它们存在。
- 如果来自单元格(0, 0)的 DFS 调用返回false ,则从左上角到右下角单元格不存在这样的路径,该路径由0s组成。因此打印0作为结果并从函数返回。
- 同样,如果来自单元格(0, 0)的 DFS 调用返回false ,那么从左上角到右下角单元格只存在一条路径,由0s组成。因此打印1作为结果并从函数返回。
- 否则,打印2作为结果。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include "bits/stdc++.h"
using namespace std;
// The four direction coordinates changes
// from the current cell
int direction[][2] = { { -1, 0 }, { 0, 1 },
{ 0, -1 }, { 1, 0 } };
// Function that returns true if there
// exists any path from the top-left to
// the bottom-right cell of 0s
bool dfs(vector >& matrix,
int i, int j, int N, int M)
{
// If the bottom-right cell is
// reached
if (i == N - 1 and j == M - 1) {
return true;
}
// Update the cell to 1
matrix[i][j] = 1;
// Traverse in all four directions
for (int k = 0; k < 4; k++) {
// Find the new coordinates
int newX = i + direction[k][0];
int newY = j + direction[k][1];
// If the new cell is valid
if (newX >= 0 and newX < N
and newY >= 0 and newY < M
and matrix[newX][newY] == 0) {
// Recursively call DFS
if (dfs(matrix, newX,
newY, N, M)) {
// If path exists, then
// return true
return true;
}
}
}
// Return false, if there doesn't
// exists any such path
return false;
}
// Function to flip the minimum number
// of cells such that there doesn't
// exists any such path from (0, 0) to
// (N - 1, M - 1) cell consisting of 0s
int solve(vector >& matrix)
{
int N = matrix.size();
int M = matrix[0].size();
// Case 1: If no such path exists
// already
if (!dfs(matrix, 0, 0, N, M)) {
return 0;
}
// Case 2: If there exists only
// one path
if (!dfs(matrix, 0, 0, N, M)) {
return 1;
}
// Case 3: If there exists two-path
return 2;
}
// Driver Code
int main()
{
vector > mat = {
{ 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 }
};
cout << solve(mat);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
class GFG{
// The four direction coordinates changes
// from the current cell
static int[][] direction = { { -1, 0 }, { 0, 1 },
{ 0, -1 }, { 1, 0 } };
// Function that returns true if there
// exists any path from the top-left to
// the bottom-right cell of 0s
static boolean dfs(int matrix[][], int i, int j,
int N, int M)
{
// If the bottom-right cell is
// reached
if (i == N - 1 && j == M - 1)
{
return true;
}
// Update the cell to 1
matrix[i][j] = 1;
// Traverse in all four directions
for(int k = 0; k < 4; k++)
{
// Find the new coordinates
int newX = i + direction[k][0];
int newY = j + direction[k][1];
// If the new cell is valid
if (newX >= 0 && newX < N && newY >= 0 &&
newY < M && matrix[newX][newY] == 0)
{
// Recursively call DFS
if (dfs(matrix, newX, newY, N, M))
{
// If path exists, then
// return true
return true;
}
}
}
// Return false, if there doesn't
// exists any such path
return false;
}
// Function to flip the minimum number
// of cells such that there doesn't
// exists any such path from (0, 0) to
// (N - 1, M - 1) cell consisting of 0s
static int solve(int[][] matrix)
{
int N = matrix.length;
int M = matrix[0].length;
// Case 1: If no such path exists
// already
if (!dfs(matrix, 0, 0, N, M))
{
return 0;
}
// Case 2: If there exists only
// one path
if (!dfs(matrix, 0, 0, N, M))
{
return 1;
}
// Case 3: If there exists two-path
return 2;
}
// Driver code
public static void main(String[] args)
{
int[][] mat = { { 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 } };
System.out.println(solve(mat));
}
}
// This code is contributed by MuskanKalra1
Python3
# Python3 program for the above approach
# The four direction coordinates changes
# from the current cell
direction = [ [ -1, 0 ], [ 0, 1 ],
[ 0, -1 ],[ 1, 0 ] ]
# Function that returns true if there
# exists any path from the top-left to
# the bottom-right cell of 0s
def dfs(i, j, N, M):
global matrix
# If the bottom-right cell is
# reached
if (i == N - 1 and j == M - 1):
return True
# Update the cell to 1
matrix[i][j] = 1
# Traverse in all four directions
for k in range(4):
# Find the new coordinates
newX = i + direction[k][0]
newY = j + direction[k][1]
# If the new cell is valid
if (newX >= 0 and newX < N and
newY >= 0 and newY < M and
matrix[newX][newY] == 0):
# Recursively call DFS
if (dfs(newX, newY, N, M)):
# If path exists, then
# return true
return True
# Return false, if there doesn't
# exists any such path
return False
# Function to flip the minimum number
# of cells such that there doesn't
# exists any such path from (0, 0) to
# (N - 1, M - 1) cell consisting of 0s
def solve():
global matrix
N = len(matrix)
M = len(matrix[0])
# Case 1: If no such path exists
# already
if (not dfs(0, 0, N, M)):
return 0
# Case 2: If there exists only
# one path
if (not dfs(0, 0, N, M)):
return 1
# Case 3: If there exists two-path
return 2
# Driver Code
if __name__ == '__main__':
matrix = [ [ 0, 1, 0, 0 ],
[ 0, 1, 0, 0 ],
[ 0, 0, 0, 0 ] ]
print(solve())
# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
class GFG{
// The four direction coordinates changes
// from the current cell
static int[,] direction = { { -1, 0 }, { 0, 1 },
{ 0, -1 }, { 1, 0 } };
// Function that returns true if there
// exists any path from the top-left to
// the bottom-right cell of 0s
static bool dfs(int [,]matrix, int i, int j,
int N, int M)
{
// If the bottom-right cell is
// reached
if (i == N - 1 && j == M - 1)
{
return true;
}
// Update the cell to 1
matrix[i, j] = 1;
// Traverse in all four directions
for(int k = 0; k < 4; k++)
{
// Find the new coordinates
int newX = i + direction[k, 0];
int newY = j + direction[k, 1];
// If the new cell is valid
if (newX >= 0 && newX < N && newY >= 0 &&
newY < M && matrix[newX, newY] == 0)
{
// Recursively call DFS
if (dfs(matrix, newX, newY, N, M))
{
// If path exists, then
// return true
return true;
}
}
}
// Return false, if there doesn't
// exists any such path
return false;
}
// Function to flip the minimum number
// of cells such that there doesn't
// exists any such path from (0, 0) to
// (N - 1, M - 1) cell consisting of 0s
static int solve(int[,] matrix)
{
int N = matrix.GetLength(0);
int M = matrix.GetLength(1);
// Case 1: If no such path exists
// already
if (!dfs(matrix, 0, 0, N, M))
{
return 0;
}
// Case 2: If there exists only
// one path
if (!dfs(matrix, 0, 0, N, M))
{
return 1;
}
// Case 3: If there exists two-path
return 2;
}
// Driver code
public static void Main(String[] args)
{
int[,] mat = { { 0, 1, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 0 } };
Console.WriteLine(solve(mat));
}
}
// This code is contributed by gauravrajput1
Javascript
1
时间复杂度: O(N + M)
辅助空间: O(1)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。