public void dfs(参数) {
if (终止条件) {
存放结果;
return;
}
for (选择:本节点所连接的其他节点){
处理节点
dfs(图,选择的节点); // 递归
回溯,撤销处理结果
}
}
public void bfs (){
Deque<> deque = new LinkedList<>();
deque初始化
while (!deque.isEmpty()) {
for (){
处理本层数据
}
}
}
n
个节点的 有向无环图(DAG),请你找出所有从节点 0
到节点 n-1
的路径并输出(不要求按特定顺序)class Solution {
List> lists = new ArrayList<>();
List list = new ArrayList<>();
public List> allPathsSourceTarget(int[][] graph) {
// dfs
list.add(0);
dfs(0, graph);
return lists;
}
public void dfs(int start, int[][] graph) {
if (start == graph.length - 1) {
lists.add(new ArrayList<>(list));
return;
}
for (int i = 0; i < graph[start].length; i++) {
list.add(graph[start][i]);
dfs(graph[start][i], graph);
list.remove(list.size() - 1);
}
}
}
给你一个由 '1'
(陆地)和 '0'
(水)组成的的二维网格,请你计算网格中岛屿的数量。岛屿总是被水包围,并且每座岛屿只能由水平方向和/或竖直方向上相邻的陆地连接形成。此外,你可以假设该网格的四条边均被水包围。
class Solution {
public int numIslands(char[][] grid) {
int res = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == '0') {
continue;
}
res++;
bfs(i, j, grid);
}
}
return res;
}
// dfs
public void dfs(int row, int col, char[][] grid) {
if (row < 0 || col < 0 || row >= grid.length || col >= grid[0].length || grid[row][col] == '0') {
return;
}
grid[row][col] = '0';
dfs(row + 1, col, grid);
dfs(row - 1, col, grid);
dfs(row, col + 1, grid);
dfs(row, col - 1, grid);
}
// BFS
public void bfs(int row, int col, char[][] grid) {
Deque deque = new LinkedList<>();
deque.offer(new int[] { row, col });
while (!deque.isEmpty()) {
for (int i = deque.size(); i > 0; i--) {
int[] poll = deque.poll();
int a = poll[0];
int b = poll[1];
if (a < 0 || b < 0 || a >= grid.length || b >= grid[0].length || grid[a][b] == '0') {
continue;
}
grid[a][b] = '0';
deque.offer(new int[] { a + 1, b });
deque.offer(new int[] { a - 1, b });
deque.offer(new int[] { a, b + 1 });
deque.offer(new int[] { a, b - 1 });
}
}
}
}
给你一个大小为 m x n
的二进制矩阵 grid
。岛屿 是由一些相邻的 1
(代表土地) 构成的组合,这里的「相邻」要求两个 1
必须在 水平或者竖直的四个方向上 相邻。你可以假设 grid
的四个边缘都被 0
(代表水)包围着。岛屿的面积是岛上值为 1
的单元格的数目。计算并返回 grid
中最大的岛屿面积。如果没有岛屿,则返回面积为 0
。
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int res = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 0) {
continue;
}
res = Math.max(res, bfs(i, j, grid));
}
}
return res;
}
public int dfs(int row, int col, int[][] grid) {
if (row < 0 || col < 0 || row >= grid.length || col >= grid[0].length || grid[row][col] == 0) {
return 0;
}
grid[row][col] = 0;
return 1 + dfs(row + 1, col, grid) + dfs(row - 1, col, grid) + dfs(row, col + 1, grid)
+ dfs(row, col - 1, grid);
}
public int bfs(int row, int col, int[][] grid) {
int[][] dir = new int[][] { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
Deque deque = new LinkedList<>();
deque.offer(new int[] { row, col });
grid[row][col] = 0;
int res = 1;
while (!deque.isEmpty()) {
int[] poll = deque.poll();
for (int i = 0; i < 4; i++) {
int a = poll[0] + dir[i][0];
int b = poll[1] + dir[i][1];
if (a < 0 || b < 0 || a >= grid.length || b >= grid[0].length || grid[a][b] == 0) {
continue;
}
grid[a][b] = 0;
res++;
deque.offer(new int[]{a, b});
}
}
return res;
}
}
给你一个大小为 m x n
的二进制矩阵 grid
,其中 0
表示一个海洋单元格、1
表示一个陆地单元格。一次 移动 是指从一个陆地单元格走到另一个相邻(上、下、左、右)的陆地单元格或跨过 grid
的边界。返回网格中 无法 在任意次数的移动中离开网格边界的陆地单元格的数量。
class Solution {
boolean mark = false;
int temp = 0;
public int numEnclaves(int[][] grid) {
int res = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1){
dfs(i, j, grid);
if (!mark){
res += temp;
}
}
mark = false;
temp = 0;
}
}
return res;
}
private void dfs(int x, int y, int[][] grid) {
if (x < 0 || x > grid.length - 1 || y < 0 || y > grid[0].length - 1) {
mark = true;
return;
}
if (grid[x][y] == 0) {
return;
}
grid[x][y] = 0;
temp++;
dfs(x + 1, y, grid);
dfs(x - 1, y, grid);
dfs(x, y + 1, grid);
dfs(x, y - 1, grid);
}
}
m x n
的矩阵 board
,由若干字符 'X'
和 'O'
,找到所有被 'X'
围绕的区域,并将这些区域里所有的 'O'
用 'X'
填充。class Solution {
char[][] res;
public void solve(char[][] board) {
res = new char[board.length][board[0].length];
for (char[] r : res) {
Arrays.fill(r, 'X');
}
for (int i = 0; i < board.length; i++) {
for (int j = 0; j < board[0].length; j++) {
if (board[i][j] == 'O' && (i == 0 || j == 0 || i == board.length - 1 || j == board[0].length - 1)) {
dfs(i, j, board);
}
}
}
for (int i = 0; i < board.length; i++) {
System.arraycopy(res[i], 0, board[i], 0, board[0].length);
}
}
public void dfs(int row, int col, char[][] board) {
if (row < 0 || col < 0 || row >= board.length || col >= board[0].length || board[row][col] == 'X') {
return;
}
board[row][col] = 'X';
res[row][col] = 'O';
dfs(row + 1, col, board);
dfs(row - 1, col, board);
dfs(row, col + 1, board);
dfs(row, col - 1, board);
}
}
class Solution {
int[][] dir = new int[][] { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
public List> pacificAtlantic(int[][] heights) {
List> list = new ArrayList<>();
boolean[][] usedA = new boolean[heights.length][heights[0].length];
boolean[][] usedP = new boolean[heights.length][heights[0].length];
for (int i = 0; i < heights.length; i++) {
dfs(i, 0, heights, usedP);
dfs(i, heights[0].length - 1, heights, usedA);
}
for (int j = 0; j < heights[0].length; j++) {
dfs(0, j, heights, usedP);
dfs(heights.length - 1, j, heights, usedA);
}
for (int i = 0; i < heights.length; i++) {
for (int j = 0; j < heights[0].length; j++) {
if (usedA[i][j] && usedP[i][j]) {
int a = i;
int b = j;
list.add(new ArrayList<>() {
{
add(a);
add(b);
}
});
}
}
}
return list;
}
public void dfs(int row, int col, int[][] heights, boolean[][] used) {
if (used[row][col]) {
return;
}
used[row][col] = true;
for (int i = 0; i < 4; i++) {
int a = row + dir[i][0];
int b = col + dir[i][1];
if (a < 0 || b < 0 || a > heights.length - 1 || b > heights[0].length - 1
|| heights[row][col] > heights[a][b]) {
continue;
}
dfs(a, b, heights, used);
}
}
}
给你一个大小为 n x n
二进制矩阵 grid
。最多 只能将一格 0
变成 1
。返回执行此操作后,grid
中最大的岛屿面积是多少?
class Solution {
int temp = 2;
int[][] dir = new int[][] { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
public int largestIsland(int[][] grid) {
Map map = new HashMap<>();
map.put(0, 0);
// 岛屿变成面积
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 1) {
map.put(temp, dfs(i, j, grid));
temp++;
}
}
}
int res = map.get(grid[0][0]);
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 0) {
int temp = 1;
Set set = new HashSet<>();
for (int k = 0; k < 4; k++) {
int a = i + dir[k][0];
int b = j + dir[k][1];
if (a < 0 || b < 0 || a > grid.length - 1 || b > grid[0].length - 1) {
continue;
}
set.add(grid[a][b]);
}
for (int s : set) {
temp += map.get(s);
}
res = Math.max(res, temp);
}
}
}
return res;
}
public int dfs(int row, int col, int[][] grid) {
if (row < 0 || col < 0 || row > grid.length - 1 || col > grid[0].length - 1 || grid[row][col] != 1) {
return 0;
}
grid[row][col] = temp;
return dfs(row + 1, col, grid) + dfs(row - 1, col, grid) + dfs(row, col + 1, grid) + dfs(row, col - 1, grid)
+ 1;
}
}
wordList
中从单词 beginWord
和 endWord
的 转换序列 是一个按下述规格形成的序列 beginWord -> s1 -> s2 -> ... -> sk
class Solution {
// 最短路径BFS
public int ladderLength(String beginWord, String endWord, List wordList) {
if (!wordList.contains(endWord)) {
return 0;
}
Set set = new HashSet<>(wordList);
Map map = new HashMap<>();
Deque deque = new LinkedList<>();
map.put(beginWord, 1);
deque.offer(beginWord);
while (!deque.isEmpty()) {
String poll = deque.poll();
int path = map.get(poll);
for (int i = 0; i < poll.length(); i++) {
char[] chs = poll.toCharArray();
for (char j = 'a'; j <= 'z'; j++) {
chs[i] = j;
String newWord = String.valueOf(chs);
if (newWord.equals(endWord)) {
return path + 1;
}
if (set.contains(newWord) && !map.containsKey(newWord)) {
deque.offer(newWord);
map.put(newWord, path + 1);
}
}
}
}
return 0;
}
}
class Solution {
boolean[] used;
public boolean canVisitAllRooms(List> rooms) {
used = new boolean[rooms.size()];
used[0] = true;
dfs(0, rooms);
for (boolean use : used) {
if (!use) {
return false;
}
}
return true;
}
public void dfs(int start, List> rooms) {
for (int index : rooms.get(start)) {
if (used[index]) {
continue;
}
used[index] = true;
dfs(index, rooms);
}
}
}
class Solution {
int[][] dir = new int[][] { { 1, 0 }, { -1, 0 }, { 0, 1 }, { 0, -1 } };
public int islandPerimeter(int[][] grid) {
int res = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
if (grid[i][j] == 0) {
continue;
}
for (int k = 0; k < 4; k++) {
int a = i + dir[k][0];
int b = j + dir[k][1];
if (a < 0 || b < 0 || a > grid.length - 1 || b > grid[0].length - 1 || grid[a][b] == 0) {
res++;
}
}
}
}
return res;
}
}