将两个岛屿连接成网格的最小水陆转换次数 |设置 2
给定一个'W'和'L'的 2D 网格arr[][] ,其中'W'表示水, 'L'表示陆地,任务是找到必须更改为陆地的水分量'W'的最小数量组件“L” ,使两个岛连接起来。
An island is the set of connected ‘L’s
注意:只能有两个不相交的岛屿。
例子:
Input: arr[][] = {{‘W’, ‘L’}, {‘L’, ‘W’}};
Output: 1
Explanation: For the given set of islands if we change arr[1][1] to ‘W’
then, set of all island are connected.
Therefore, the minimum number of ‘W’ must be changed to ‘L’ is 1.
Input: arr[][] = {{‘W’, ‘L’, ‘W’}, {‘W’, ‘W’, ‘W’}, {‘W’, ‘W’, ‘L’}}
Output: 2
基于Floodfill算法的方法:本文的Set-1讨论了基于Floodfill算法的方法。
高效方法:这个问题可以通过使用DFS 和 BFS 算法来解决。这个想法是使用 DFS 找到一个岛屿的所有陆地组件,同时将边界陆地组件添加到队列中,该队列将在 BFS 中用于扩展并找到到第二个岛屿的最短路径。请按照以下步骤解决问题:
- 使用嵌套循环在arr[][]中查找'L'的第一次出现。
- 调用 DFS 查找该岛的所有元素,如果任何“L”是边界元素(即至少在一侧被“W”包围),也将其添加到队列中。
- 使用 BFS 算法使用DFS 调用期间创建的队列和访问数组扩展此岛。
- 在每个级别将距离增加1 。
- 通过使用BFS找到从一个岛的边界到第二个岛的最小路径。
- 如果要添加到队列中的下一个组件是'L' ,则返回到现在为止的距离。
注意:第一个岛的所有元素也可以使用 BFS 算法找到。
下面是上述方法的实现:
Java
// Java program to implement the approach
import java.util.*;
class GFG {
static int R;
static int C;
// A class to represent point and
// dist from first island
static class qNode {
int x;
int y;
int dist;
qNode(int x, int y, int d)
{
this.x = x;
this.y = y;
this.dist = d;
}
}
// Function to find minimum conversions
static int minConversions(char[][] arr)
{
R = arr.length;
C = arr[0].length;
// Queue to be used in bfs
Queue q = new ArrayDeque<>();
boolean[][] visited
= new boolean[R][C];
boolean flag = false;
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (arr[i][j] == 'L') {
// Visited first island
// completely and at
// same time maintaining
// visited array and queue
dfs(i, j, visited, q, arr);
flag = true;
break;
}
}
// Breaking the nested loop
// once first island found
if (flag)
break;
}
return bfs(q, visited, arr);
}
// Arrays to get the adjacent indices
// from one index of thegrid
static int[] dirx = { 0, 1, 0, -1 };
static int[] diry = { 1, 0, -1, 0 };
// Function to run DFS
static void dfs(int i, int j,
boolean[][] visited,
Queue q,
char[][] arr)
{
visited[i][j] = true;
// Checking if it is border component
if (isBorder(i, j, arr)) {
q.add(new qNode(i, j, 0));
}
// Calling dfs in all 4 directions
for (int idx = 0; idx < 4; idx++) {
int x = i + dirx[idx];
int y = j + diry[idx];
if (isValid(x, y)
&& arr[x][y] == 'L'
&& !visited[x][y]) {
dfs(x, y, visited, q, arr);
}
}
}
// Return true if surrounded by water
// in any of 4 direction
static boolean isBorder(int i, int j,
char[][] arr)
{
for (int idx = 0; idx < 4; idx++) {
int x = i + dirx[idx];
int y = j + diry[idx];
if (isValid(x, y)
&& arr[x][y] == 'W')
return true;
}
return false;
}
// Function to implement BFS
static int bfs(Queue q,
boolean[][] visited,
char[][] arr)
{
while (q.size() > 0) {
qNode p = q.remove();
for (int idx = 0; idx < 4;
idx++) {
int x = p.x + dirx[idx];
int y = p.y + diry[idx];
// If next unvisited component
// is land, return dist
// till of p only
if (isValid(x, y)
&& arr[x][y] == 'L'
&& !visited[x][y]) {
return p.dist;
}
if (isValid(x, y)
&& arr[x][y] == 'W'
&& !visited[x][y]) {
q.add(new qNode(x, y,
p.dist + 1));
visited[x][y] = true;
}
}
}
return -1;
}
// To check if indices are in matrix
static boolean isValid(int x, int y)
{
if (x < 0 || y < 0
|| x >= R || y >= C)
return false;
return true;
}
// Driver Code
public static void main(String[] args)
{
char[][] arr = { { 'W', 'L', 'W' },
{ 'W', 'W', 'W' },
{ 'W', 'W', 'L' } };
// Function call
int ans = minConversions(arr);
System.out.println(ans);
}
}
C#
// C# program to implement the approach
using System;
using System.Collections.Generic;
public class GFG {
static int R;
static int C;
// A class to represent point and
// dist from first island
class qNode {
public int x;
public int y;
public int dist;
public qNode(int x, int y, int d)
{
this.x = x;
this.y = y;
this.dist = d;
}
}
// Function to find minimum conversions
static int minConversions(char[,] arr)
{
R = arr.Length;
C = arr.GetLength(0);
// Queue to be used in bfs
Queue q = new Queue();
bool[,] visited
= new bool[R,C];
bool flag = false;
for (int i = 0; i < R; i++) {
for (int j = 0; j < C; j++) {
if (arr[i,j] == 'L') {
// Visited first island
// completely and at
// same time maintaining
// visited array and queue
dfs(i, j, visited, q, arr);
flag = true;
break;
}
}
// Breaking the nested loop
// once first island found
if (flag)
break;
}
return bfs(q, visited, arr);
}
// Arrays to get the adjacent indices
// from one index of thegrid
static int[] dirx = { 0, 1, 0, -1 };
static int[] diry = { 1, 0, -1, 0 };
// Function to run DFS
static void dfs(int i, int j,
bool[,] visited,
Queue q,
char[,] arr)
{
visited[i,j] = true;
// Checking if it is border component
if (isBorder(i, j, arr)) {
q.Enqueue(new qNode(i, j, 0));
}
// Calling dfs in all 4 directions
for (int idx = 0; idx < 4; idx++) {
int x = i + dirx[idx];
int y = j + diry[idx];
if (isValid(x, y)
&& arr[x,y] == 'L'
&& !visited[x,y]) {
dfs(x, y, visited, q, arr);
}
}
}
// Return true if surrounded by water
// in any of 4 direction
static bool isBorder(int i, int j,
char[,] arr)
{
for (int idx = 0; idx < 4; idx++) {
int x = i + dirx[idx];
int y = j + diry[idx];
if (isValid(x, y)
&& arr[x,y] == 'W')
return true;
}
return false;
}
// Function to implement BFS
static int bfs(Queue q,
bool[,] visited,
char[,] arr)
{
while (q.Count > 0) {
qNode p = q.Dequeue();
for (int idx = 0; idx < 4;
idx++) {
int x = p.x + dirx[idx];
int y = p.y + diry[idx];
// If next unvisited component
// is land, return dist
// till of p only
if (isValid(x, y)
&& arr[x,y] == 'L'
&& !visited[x,y]) {
return p.dist;
}
if (isValid(x, y)
&& arr[x,y] == 'W'
&& !visited[x,y]) {
q.Enqueue(new qNode(x, y,
p.dist + 1));
visited[x,y] = true;
}
}
}
return -1;
}
// To check if indices are in matrix
static bool isValid(int x, int y)
{
if (x < 0 || y < 0
|| x >= R || y >= C)
return false;
return true;
}
// Driver Code
public static void Main(String[] args)
{
char[,] arr = { { 'W', 'L', 'W' },
{ 'W', 'W', 'W' },
{ 'W', 'W', 'L' } };
// Function call
int ans = minConversions(arr);
Console.WriteLine(ans);
}
}
// This code is contributed by shikhasingrajput
2
时间复杂度: O(N 2 )
辅助空间: O(N 2 )