第二十二天
2000 反转单词前缀
给你一个下标从0
开始的字符串word
和一个字符ch
。找出ch
第一次出现的下标i
,反转word
中从下标0
开始、直到下标i
结束(含下标i
)的那段字符。如果word
中不存在字符ch
,则无需进行任何操作。
例如,如果 word = "abcdefd"
且 ch = "d"
,那么你应该 反转 从下标0
开始、直到下标3
结束(含下标3
)。结果字符串将会是 "dcbaefd"
。
返回 结果字符串 。
方法
从头往后扫,找到目标字符,反转即可。
class Solution {
public String reversePrefix(String word, char ch) {
int end = -1;
StringBuilder sb = new StringBuilder();
for (int i = 0; i < word.length(); ++i){
sb.append(word.charAt(i));
if (word.charAt(i) == ch) {
end = i;
break;
}
}
if (end == -1) return sb.toString();
return sb.reverse().toString() + word.substring(end + 1, word.length());
}
}
1091 二进制矩阵中的最短路径
给你一个n x n
的二进制矩阵 grid
中,返回矩阵中最短 畅通路径 的长度。如果不存在这样的路径,返回-1
。
二进制矩阵中的 畅通路径 是一条从 左上角 单元格(即,(0, 0)
)到 右下角 单元格(即,(n - 1, n - 1)
)的路径,该路径同时满足下述要求:
路径途经的所有单元格都的值都是 0
。
路径中所有相邻的单元格应当在 8 个方向之一 上连通(即,相邻两单元之间彼此不同且共享一条边或者一个角)。
畅通路径的长度 是该路径途经的单元格总数。
方法 BFS
从开始节点开始,进行广度优先搜索,每次判断时记录当前的step
,当到目标位置时,直接返回step
值即可。注意边界条件的判断,开始位置不能为1
,以及如果找不到这个答案,也需要返回-1
。
class Solution {
public static boolean[][] isVisited;
public static int[] dirX = {0, 0, 1, -1, 1, 1, -1, -1};//八个方向
public static int[] dirY = {1, -1, 0, 0, 1, -1, 1, -1};
public int shortestPathBinaryMatrix(int[][] grid) {
if (grid[0][0] == 1) return -1;
if (grid[0][0] == 0 && grid.length == 1) return 1;
int res = -1;
int length = grid.length;
isVisited = new boolean[length][length];
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{0, 0, 1});
while (!queue.isEmpty()){
int[] temp = queue.poll();
int x = temp[0];
int y = temp[1];
int step = temp[2];
isVisited[x][y] = true;
for (int i = 0; i < 8; ++i) {
int newX = x + dirX[i];
int newY = y + dirY[i];
int newStep = step + 1;
if (newX >= 0 && newX < length && newY >= 0 && newY < length
&& !isVisited[newX][newY] && grid[newX][newY] == 0){
queue.offer(new int[]{newX, newY, newStep});
isVisited[newX][newY] = true;
if (newX == length - 1 && newY == length - 1) return newStep;
}
}
}
return res;
}
}
130 被包围的区域
给你一个 m x n
的矩阵 board
,由若干字符'X'
和'O'
,找到所有被 'X'
围绕的区域,并将这些区域里所有的'O'
用'X'
填充。
方法
使用广度优先搜索处理这个问题,具体的方法是首先将边界上的O
全部找出来,然后将其加入到带访问的队列中去,然后以这个队列为基础开始BFS
。将所有经过的点都标记为true
,返回答案时,将标记为true
的位置置为O
,其他地方置为X
。
class Solution {
public static boolean[][] isVisited;
public static int[] dX = {0, 0, 1, -1};
public static int[] dY = {1, -1, 0, 0};
public void solve(char[][] board) {
Queue<int[]> queue = new LinkedList<>();
int xLength = board.length;
int yLength = board[0].length;
isVisited = new boolean[xLength][yLength];
for (int i = 0; i < yLength; ++i) {
if (board[0][i] == 'O' && !isVisited[0][i]) {
queue.offer(new int[]{0, i});
isVisited[0][i] = true;
}
if (board[xLength - 1][i] == 'O' && !isVisited[xLength - 1][i]) {
queue.offer(new int[]{xLength - 1, i});
isVisited[xLength - 1][i] = true;
}
}
for (int i = 0; i < xLength; ++i) {
if (board[i][0] == 'O' && !isVisited[i][0]) {
queue.offer(new int[]{i, 0});
isVisited[i][0] = true;
}
if (board[i][yLength - 1] == 'O' && !isVisited[i][yLength - 1]) {
queue.offer(new int[]{i, yLength - 1});
isVisited[i][yLength - 1] = true;
}
}
while (!queue.isEmpty()){
int[] temp = queue.poll();
int x = temp[0];
int y = temp[1];
isVisited[x][y] = true;
for (int i = 0; i < 4; ++i){
int newX = x + dX[i];
int newY = y + dY[i];
if (newX >= 0 && newX < xLength && newY >= 0 && newY < yLength
&& !isVisited[newX][newY] && board[newX][newY] == 'O') {
queue.offer(new int[]{newX, newY});
isVisited[newX][newY] = true;
}
}
}
for (int i = 0; i < xLength; ++i) {
for (int j = 0; j < yLength; ++j)
if (isVisited[i][j]) board[i][j] = 'O';
else board[i][j] = 'X';
}
}
}
797 所有可能的路径
给你一个有 n
个节点的 有向无环图(DAG),请你找出所有从节点0
到节点n-1
的路径并输出(不要求按特定顺序)
graph[i]
是一个从节点i
可以访问的所有节点的列表(即从节点 i
到节点 graph[i][j]
存在一条有向边)。
方法
这是一道回溯题,当访问到某一个节点时,首先将这个节点标记为已访问,回溯时,将这个节点重新标记为未访问即可,同时维护一个array
用于保存结果。
class Solution {
public static int n;
public static boolean[] isUsed;
public static ArrayList<Integer> route;
public static List<List<Integer>> res;
public List<List<Integer>> allPathsSourceTarget(int[][] graph) {
n = graph.length;
route = new ArrayList<>();
isUsed = new boolean[n];
res = new ArrayList<>();
deepFirstSearch(0, graph);
return res;
}
public static void deepFirstSearch(int current, int[][] graph){
int[] toBeVisited = graph[current];
route.add(current);
if (current == n - 1){
res.add(new ArrayList<>(route));
return;
}
for (int i : toBeVisited){
if (!isUsed[i]){
isUsed[i] = true;
deepFirstSearch(i, graph);
isUsed[i] = false;
route.remove(route.size() - 1);
}
}
}
}