[分析]
思路1:和Number of Islands类似,但是此题用DFS会栈溢出,因此使用BFS。从四个边缘的元素开始BFS, 遇到 O 改成特殊字符M,最后没有被修改的O就是被X包围的,应当改为X, 并且把M恢复成O即可。 BFS搜索时队列中维护的是所有未展开BFS的 O,队列记录这些 O的位置。
思路2:利用union find算法,将所有边界可达的O union在一起。设置一个根节点oRoot,边界上的所有O同其union上,非边界的O同其上下左右的O进行union。扫描完board后,那些最终没有和oRoot union在一起的O是需要翻转的。实现时特别注意要将oRoot的秩设得足够大,比如设为矩阵元素个数,确保每个oRoot始终是边界可达O集合的根元素。因为在大矩阵情况下,中间可能产生比较大的秩,若oRoot秩比较小,根元素会被替换从而出错。
对比Number of Islands, 这里使用一维数组实现union find内部数据结构更简洁。
// Method 2: Union Find
public class Solution {
public void solve(char[][] board) {
if (board == null || board.length == 0 || board[0].length == 0)
return;
int rows = board.length, cols = board[0].length;
int oRoot = rows * cols;
initUnionFind(rows * cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (board[i][j] == 'X') continue;
int curr = i * cols + j;
if (i == 0 || i == rows - 1 || j == 0 || j == cols - 1) {
union(curr, oRoot);
} else {
if (j + 1 < cols && board[i][j + 1] == 'O')
union(curr, i * cols + j + 1);
if (j - 1 >= 0 && board[i][j - 1] == 'O')
union(curr, i * cols + j - 1);
if (i + 1 < rows && board[i + 1][j] == 'O')
union(curr, (i + 1) * cols + j);
if (i - 1 >= 0 && board[i - 1][j] == 'O')
union(curr, (i - 1) * cols + j);
}
}
}
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (board[i][j] == 'O' && find(i * cols + j) != oRoot) {
board[i][j] = 'X';
}
}
}
}
int[] s;
int[] rank;
private void initUnionFind(int n) {
s = new int[n + 1];
rank = new int[n + 1];
for (int i = 0; i <= n; i++)
s[i] = i;
rank[n] = n + 1;
}
private int find(int p) {
if (s[p] == p) return p;
else return s[p] = find(s[p]);
}
private void union(int p, int q) {
int pRoot = find(p), qRoot = find(q);
if (pRoot == qRoot) return;
if (rank[pRoot] < rank[qRoot]) {
s[pRoot] = qRoot;
} else {
if (rank[pRoot] == rank[qRoot])
rank[pRoot]++;
s[qRoot] = pRoot;
}
}
}
// Method 1 BFS
public class Solution {
public void solve(char[][] board) {
if (board == null || board.length == 0 || board[0].length == 0)
return;
int m = board.length, n = board[0].length;
for (int j = 0; j < n; j++) {
if (board[0][j] == 'O') bfs(0, j, board); // row 0
if (board[m - 1][j] == 'O') bfs(m - 1, j, board); // last row
}
for (int i = 0; i < m; i++) {
if (board[i][0] == 'O') bfs(i, 0, board); // col 0
if (board[i][n - 1] == 'O') bfs(i, n - 1, board); // last col
}
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if (board[i][j] == 'O') board[i][j] = 'X';
else if (board[i][j] == 'M') board[i][j] = 'O';
}
}
}
public void bfs(int i, int j, char[][] board) {
LinkedList<Integer> queue = new LinkedList<Integer>();
visit(i, j, board, queue);
while (!queue.isEmpty()) {
int idx = queue.poll();
int r = idx / board[0].length;
int c = idx % board[0].length;
visit(r - 1, c, board, queue);
visit(r + 1, c, board, queue);
visit(r, c - 1, board, queue);
visit(r, c + 1, board, queue);
}
}
public void visit(int i, int j, char[][] board, LinkedList<Integer> queue) {
if (i < 0 || i >= board.length || j < 0 || j >= board[0].length || board[i][j] != 'O')
return;
board[i][j] = 'M';
queue.offer(i * board[0].length + j);
}
}
分享到:
相关推荐
《在IDE中高效进行LeetCode练习:leetcode-editor的深度解析》 在编程学习与技能提升的过程中,LeetCode作为一款广受欢迎的在线编程挑战平台,帮助众多开发者锻炼算法思维,提高编程能力。而为了进一步提升练习体验...
在IDE中解决LeetCode问题,支持leetcode.com与leetcode-cn.com,满足基本的做题需求。 理论上支持: IntelliJ IDEA PhpStorm WebStorm PyCharm RubyMine AppCode CLion GoLand DataGrip Rider MPS Android Studio。
leetcode-cli-plugins leetcode-cli 的第 3 方插件。 什么是 如何使用 如何使用 插件 名称 描述 增强的命令 按公司或标签过滤问题 list 不要在同一台计算机上使 Chrome 的会话过期 login 不要在同一台计算机上使 ...
LeetCode Editor 7.4 版本的下载是一个名为 "leetcode-editor" 的压缩包文件。这个压缩包的导入过程非常简单,只需要将它直接拖入 IDEA 界面,IDEA 会自动识别并安装插件。这种方式使得安装过程无需额外的步骤,对于...
~/.vscode/extensions/leetcode.vscode-leetcode-0.17.0/node_modules/vsc-leetcode-cli/bin/leetcode /usr/local/bin/leetcode 修改模板 open ~/.vscode/extensions/leetcode.vscode-leetcode-0.17.0/node_modules/...
leetcode-习题集资源leetcode-习题集资源leetcode-习题集资源leetcode-习题集资源leetcode-习题集资源leetcode-习题集资源
解题思路思路和LeetCode-python 503.下一个更大元素 II一致,只是这里求的是下标的距离,而不是数值倒序搜索,用到栈,栈里存储索引情况1:若栈为
《PyPI官网下载 | leetcode-export-1.1.tar.gz》 在编程世界里,LeetCode是一个备受程序员喜爱的在线平台,它提供了大量的算法题目,帮助开发者提升编程技能和解决问题的能力。而Python作为一门广泛使用的高级编程...
leetcode-习题集资源源代码leetcode-习题集资源源代码leetcode-习题集资源源代码leetcode-习题集资源源代码leetcode-习题集资源源代码
leetcode-cheat 的发布 它是什么 ? 这是一个chrome 扩展,可以帮助您更高效地使用 leetcode。您可以从 重要: leetcode-cheat 现在只支持中文版。 也就是说不完全支持leetcode.com,但是你可以用leetcode-cn.com代替...
`swift-Swif-LeetCode-Utils` 是一个实用工具库,它为Swift程序员提供了方便快捷的方法来处理这些问题。这个项目可以帮助你更高效地进行LeetCode上的编程练习,提升你的解决方案的可读性和简洁性。 首先,让我们...
java java_leetcode-115-distinct-subsquences
java java_leetcode-112-path-sum
java java_leetcode-101-symmetric-tree
java java_leetcode-100-same-tree
970. 强整数对数运算function powerfulIntegers(x: number, y: number, bound: number): numb
java java_leetcode-110-balanced-binary-tree
java java_leetcode-73-set-matrix-zeroes
然后进入到LeetCode-Spider目录中修改config.json,其中outputDir需要填写该工程的/docs/views文件夹路径 { "username": "aaa", "password": "bbb", "outputDir": "/Users/liuyao/Downloads/LeetCode-Blog-Test/docs...