【发布时间】:2021-08-19 05:35:18
【问题描述】:
这是计算网格中岛屿数量的代码。给定一个m x n 二维二进制网格,它表示'1's(陆地)和'0's(水)的地图,返回岛屿的数量。岛屿四面环水,由相邻陆地水平或垂直连接而成。您可以假设网格的所有四个边缘都被水包围。
(这是leetcode的问题)
例如-
输入:网格 =
[
["1","1","0","0","0"],
["1","1","0","0","0"],
["0","0","1","0","0"],
["0","0","0","1","1"]
]
输出:3
约束:
- `m == grid.length`
- `n == grid[i].length`
- `1 <= m, n <= 300`
- `grid[i][j] is '0' or '1'.`
我通过查找连接组件的总数使用图表解决了这个问题。我使用映射将(i,j) 对指向其对应的顶点编号,使用邻接列表来存储所有边,并使用访问数组来标记已经访问过的顶点。
代码如下:
void dfs(vector<vector<int>> edges, bool *visited, int start)
{
visited[start] = true;
int n = edges[start].size();
for (int i = 0; i < n; i++)
{
if (!visited[edges[start][i]])
dfs(edges, visited, edges[start][i]);
}
}
int numIslands(vector<vector<char>> &grid)
{
int m = grid.size();
int n = grid[0].size();
int start = 0;
unordered_map<string, int> map;
//storing the ij pair as a string and giving it an integer value to make it a vertex
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (grid[i][j] == '1')
{
char first = '0' + i;
char second = '0' + j;
string str = "";
str += first;
str += second;
map[str] = start;
start++;
}
}
}
vector<vector<int>> edges(start);
//adjacency list
for (int i = 0; i < m; i++)
{
for (int j = 0; j < n; j++)
{
if (grid[i][j] == '1')
{
char first = '0' + i;
char second = '0' + j;
string str = "";
str += first;
str += second;
if (i - 1 >= 0 && grid[i - 1][j] == '1')
{
char first = '0' + (i - 1);
char second = '0' + j;
string str1 = "";
str1 += first;
str1 += second;
edges[map[str]].push_back(map[str1]);
}
if (i + 1 < m && grid[i + 1][j] == '1')
{
char first = '0' + (i + 1);
char second = '0' + j;
string str1 = "";
str1 += first;
str1 += second;
edges[map[str]].push_back(map[str1]);
}
if (j - 1 >= 0 && grid[i][j - 1] == '1')
{
char first = '0' + i;
char second = '0' + (j - 1);
string str1 = "";
str1 += first;
str1 += second;
edges[map[str]].push_back(map[str1]);
}
if (j + 1 < n && grid[i][j + 1] == '1')
{
char first = '0' + i;
char second = '0' + (j + 1);
string str1 = "";
str1 += first;
str1 += second;
edges[map[str]].push_back(map[str1]);
}
}
}
}
//counting the number of connected components
bool *visited = new bool[start];
for (int i = 0; i < start; i++)
visited[i] = false;
int ans = 0;
for (int i = 0; i < edges.size(); i++)
{
if (!visited[i])
{
ans++;
dfs(edges, visited, i);
}
}
return ans;
}
该代码适用于大多数测试用例。但是,当我输入任何列数大于 256 的一行输入时,它不会给出所需的输出(即 1)。
例如 - [['1', '1', '1', '1', '1', ....(287 times) ]] 给出 32 作为输出。
为什么会这样?
【问题讨论】:
-
它是因为第一个和第二个数据类型是 char 并且它可以达到 255
-
如果将关键字
char的所有实例都替换为int会发生什么? -
char first = '0' + i;- 没有必要把它变成一个字符,甚至根本不需要一个first变量。只需str += std::to_string(i);。看起来像这样的其他代码行也是如此。 -
char不需要能够表示大于 255 的值。而且,在大多数实现中,它不需要。char是signed还是unsigned类型是实现定义的。如果它是signed类型,则仅保证(按标准)能够表示从-127到127的值,如果它是unsigned类型,则仅保证能够表示值从0到255。如果您需要更大范围的值,请使用可以表示(至少)您需要的范围的类型。
标签: c++ algorithm graph depth-first-search