链接:
https://leetcode.com/problems/rotting-oranges/
题意:
给定一个二维矩阵,矩阵中每个元素为0,1,2三个数中的一个。已知操作:2可以把相邻(上下左右)的1转变为2。问需要多少次操作才可以将矩阵中所有的1变为2。。。说不清楚,看它给的图吧:(红色橘子为2,黄色橘子为1,空白为0)如果到最后仍有1存在,则返回-1

思路:
图的BFS。首先遍历一遍二维数组,记录数组中1的个数以及找到图的入口处(可能有多个,放到队列中)。然后类似树的BFS,借用两个变量l,ll;l用于指示当前层遍历到的位置,ll用于指示上一层最后一个元素的位置。
然后就是针对当前位置,对它的上下左右四个方向进行判断:以上方向为例。若上方向的位置在数组范围内且上位置的值为1,则把上位置的值变为2,并且把上位置加入到队列中,矩阵中1的个数减1。
最后判断矩阵中1的个数是否为0。若为0,则返回操作的次数;否则返回 -1
代码:
class Solution {
// 图的BFS
public int orangesRotting(int[][] g) {
int count = 0, maxRow = g.length - 1, maxCol = g[0].length - 1, count1 = 0; // count记录需要几次操作 count1记录g中1的个数
LinkedList<String> queue = new LinkedList<>(); // 存放值为2的点
// 先找到所有可能的顶点
String l = "",ll = "";
for (int i = 0; i < g.length; i++) {
for (int j = 0; j < g[0].length; j++) {
if (g[i][j] == 2) {
ll = i + "@" + j;
queue.add(ll);
} else if (g[i][j] == 1) {
count1++;
}
}
}
if (queue.size() == 0) {
return count1 == 0 ? 0 : -1;
}
while (!queue.isEmpty()) {
String s = queue.remove();
String[] str = s.split("@");
int row = Integer.valueOf(str[0]), col = Integer.valueOf(str[1]);
// 上位置
if (row - 1 >= 0 && g[row - 1][col] == 1) {
queue.add((row - 1) + "@" + col);
g[row - 1][col] = 2;
l = (row - 1) + "@" + col;
count1--;
}
// 下位置
if (row + 1 <= maxRow && g[row + 1][col] == 1) {
queue.add((row + 1) + "@" + col);
g[row + 1][col] = 2;
l = (row + 1) + "@" + col;
count1--;
}
// 左位置
if (col - 1 >= 0 && g[row][col - 1] == 1) {
queue.add(row + "@" + (col - 1));
g[row][col - 1] = 2;
l = row + "@" + (col - 1);
count1--;
}
// 右位置
if (col + 1 <= maxCol && g[row][col + 1] == 1) {
queue.add(row + "@" + (col + 1));
g[row][col + 1] = 2;
l = row + "@" + (col + 1);
count1--;
}
// 若此时是最后一层了 则不需要再对count加1了 比如用例:[[0,2]]
if (s.equals(ll) && !queue.isEmpty()) {
ll = l;
count++;
}
}
return count1 == 0 ? count : -1;
}
}
结果:

结论:
打击自信的结论...效率如此低。
猜测原因:如果不是思想有瑕疵,那就是数据结构有问题
最佳:
果不其然,把存储位置的数据结果由字符串改为数组,效率就蹭蹭蹭地飞了...嗨森
class Solution {
// 图的BFS
public int orangesRotting(int[][] g) {
int count = 0, maxRow = g.length - 1, maxCol = g[0].length - 1, count1 = 0; // count记录需要几次操作 count1记录g中1的个数
LinkedList<int[]> queue = new LinkedList<>(); // 存放值为2的点
// 先找到所有可能的顶点
int[] l = null, ll = null;
for (int i = 0; i < g.length; i++) {
for (int j = 0; j < g[0].length; j++) {
if (g[i][j] == 2) {
ll = new int[]{i, j};
queue.add(ll);
} else if (g[i][j] == 1) {
count1++;
}
}
}
if (queue.size() == 0) {
return count1 == 0 ? 0 : -1;
}
while (!queue.isEmpty()) {
int[] nums = queue.remove();
int row = nums[0], col = nums[1];
// 上位置
if (row - 1 >= 0 && g[row - 1][col] == 1) {
l = new int[]{row - 1, col};
queue.add(l);
g[row - 1][col] = 2;
count1--;
}
// 下位置
if (row + 1 <= maxRow && g[row + 1][col] == 1) {
l = new int[]{row + 1, col};
queue.add(l);
g[row + 1][col] = 2;
count1--;
}
// 左位置
if (col - 1 >= 0 && g[row][col - 1] == 1) {
l = new int[]{row, col - 1};
queue.add(l);
g[row][col - 1] = 2;
count1--;
}
// 右位置
if (col + 1 <= maxCol && g[row][col + 1] == 1) {
l = new int[]{row, col + 1};
queue.add(l);
g[row][col + 1] = 2;
count1--;
}
// 若此时是最后一层了 则不需要再对count加1了 比如用例:[[0,2]]
if (nums == ll && !queue.isEmpty()) {
ll = l;
count++;
}
}
return count1 == 0 ? count : -1;
}
}

博客围绕LeetCode上烂橘子问题展开,给定二维矩阵,元素为0、1、2,2可将相邻1变为2,求使所有1变为2的操作次数。采用图的BFS思路,先遍历记录1的个数和入口,再逐层判断。代码实现后效率低,后将存储位置的数据结构由字符串改为数组,效率提升。
6554

被折叠的 条评论
为什么被折叠?



