floodfill
/**
* 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。
* 一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。
* 你可以假设网格的四个边均被水包围。
*/
复制代码
- 所谓floodfill,类似于感染,滴一滴红墨水,染红周围
- 可以看作是一个dfs
思路:找到“1”,然后dfs所有与该位相连的,完整一个dfs后,res++
随之遍历整个数组
复制代码
public class NumberOfIslands {
int[][] d = {{1,0},{-1,0},{0,1},{0,-1}};
int m,n;
boolean[][] visited;
private boolean inArea(int x,int y){
return x >= 0 && x < m && y >= 0 && y < n;
}
public int numIslands(char[][] grid) {
if(grid == null||grid.length==0||grid[0].length==0){
return 0;
}
m = grid.length;
n = grid[0].length;
visited = new boolean[m][n];
int res = 0;
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if(grid[i][j]=='1'&&!visited[i][j]){
dfs(grid,i,j);
res++;
}
}
}
return res;
}
private void dfs(char[][] grid,int i,int j){
visited[i][j] = true;
for (int k = 0; k < 4; k++) {
int x = i+d[k][0];
int y = j+d[k][1];
if(inArea(x,y)&&grid[x][y]=='1'&&!visited[x][y]){
dfs(grid,x,y);
}
}
}
}
复制代码
二维平面回溯
复制代码
- 这个时候dfs是需要递归终止条件:当找到所有单词后返回
- dfs很有套路:四个方向,访问位都是最基本的
思路:主要是dfs,递归结束条件(所有的单词找到),满足条件则访问位确定
遍历四个方向
最后一定要注意:该点未找到满足条件,则回溯(访问为false)
复制代码
public class searchWord {
private int d[][] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
private int m, n;
private boolean[][] visited;
public boolean exist(char[][] board, String word) {
if(board == null || word == null)
throw new IllegalArgumentException("board&nbs***bsp;word can not be null!");
m = board.length;
if(m == 0)
throw new IllegalArgumentException("board can not be empty.");
n = board[0].length;
if(n == 0)
throw new IllegalArgumentException("board can not be empty.");
visited = new boolean[m][n];
for(int i = 0 ; i < m ; i ++)
for(int j = 0 ; j < n ; j ++)
if(searchWord(board, word, 0, i, j))
return true;
return false;
}
private boolean inArea( int x , int y ){
return x >= 0 && x < m && y >= 0 && y < n;
}
private boolean searchWord(char[][] board,String word,int index,int x,int y){
if(index == word.length()-1){
return board[x][y] == word.charAt(index);
}
if(board[x][y] == word.charAt(index)){
visited[x][y] = true;
for (int i = 0; i < 4; i++) {
int newx = x+d[i][0];
int newy = y+d[i][1];
if(inArea(newx,newy)&&!visited[newx][newy]&&searchWord(board,word,index+1,newx,newy)){
return true;
}
}
visited[x][y] = false;
}
return false;
}
}
复制代码
排列问题
给定一个没有重复数字的序列,返回其所有可能的全排列。
复制代码
N皇后问题
求 n皇后求解个数
复制代码
public class N_QueensII {
private boolean col[];
private boolean dia1[];
private boolean dia2[];
public int totalNQueens(int n) {
col = new boolean[n];
dia1 = new boolean[2 * n - 1];
dia2 = new boolean[2 * n - 1];
return putQueen(n, 0);
}
private int putQueen(int n, int index) {
int res = 0;
if (index == n) {
return 1;
}
for (int i = 0; i < n; i++) {
if (!col[i] && !dia1[i - index + n - 1] && !dia2[i + index]) {
col[i] = true;
dia1[i - index + n - 1] = true;
dia2[i + index] = true;
res += putQueen(n, index + 1);
col[i] = false;
dia1[i - index + n - 1] = false;
dia2[i + index] = false;
}
}
return res;
}
}
复制代码