Algorithms Beauty - two-dimensional depth-first and backtracking

Algorithms Beauty - two-dimensional depth-first and backtracking

Given a two-dimensional grid and a word, to find out whether the word exists in the grid.

Words must, by the letters in adjacent cells constituting alphabetically, where "adjacent" cells that are adjacent horizontally or vertically adjacent cells. Letters within the same cell is not allowed to be reused.

Example:

board =
[
  ['A','B','C','E'],
  ['S','F','C','S'],
  ['A','D','E','E']
]

给定 word = "ABCCED", 返回 true.
给定 word = "SEE", 返回 true.
给定 word = "ABCB", 返回 false.
public class SearchWord {
    static int[][] d = {{-1,0},{0,1},{1,0},{0,-1}}; 
    static int m;
    static int n;
    static boolean[][] visited;
    static char [][]b1 = { {'A','B','C','E'},
                    {'S','F','C','S'},
                    {'A','D','E','E'}};
    static String words[] = {"ABCCED", "SEE", "ABCB" };
	public static void main(String[] args) {
		for(int i=0;i<words.length;i++) {
			if(exist(b1,words[i]))  System.out.println("found " + words[i]);
            else
                System.out.println("can not found " + words[i]);
		}
	}
	private static boolean exist(char[][] board, String word) {
		// TODO Auto-generated method stub
		if(board==null||word==null) 
			throw new IllegalArgumentException("board or word can not be null!");
		m = board.length;
		n = board[0].length;
		visited = new boolean[m][n];
		for(int i=0;i<m;i++) {
			for(int j=0;j<n;j++) {
				if(FindWord(board,word,0,i,j))
				return true;
			}
		}
		return false;
	}
	private static boolean FindWord(char[][] board, String word, int index, int startx, int starty) {
		// TODO Auto-generated method stub
		if(index == word.length()) {
			return board[startx][starty] == word.charAt(index);
		}
		if(board[startx][starty]==word.charAt(index)) {
			visited[startx][starty] =true;
			for(int i =0;i<4;i++) {
				int newx = startx+d[i][0];
				int newy = startx+d[i][1];
				if(inArea(newx,newy)&&!visited[newx][newy]&&FindWord(board,word,index+1,newx,newy));
				
			}
			visited[startx][starty] =false;
			
		}
		return false;
	}
	private static boolean inArea(int newx, int newy) {
		// TODO Auto-generated method stub
		return newx>=0&&newx<m&&newy>=0&&newy<n;
	}
}

Output:

 

Classic Case

Given consisting of  '1'(land), and  '0'(water) consisting of two-dimensional grid, the number of islands of computing. An island surrounded by water, and it is through the horizontal or vertical direction is connected to each adjacent land. You can assume that the water surrounding the four sides of the grid are.

Example 1:

输入:
11110
11010
11000
00000

输出: 1

Example 2:

输入:
11000
11000
00100
00011

输出: 3
public class IsandsFind {
   static int d[][] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
   static int m;
   static int n;
   static boolean[][] visited;
   static char[][] grid = {
           {'1','1','1','1','0'},
           {'1','1','0','1','0'},
           {'1','1','0','0','0'},
           {'0','0','0','0','0'}
       };
	public static void main(String[] args) {
		if(grid==null||grid.length==0||grid[0].length==0) {
			System.out.println(0);
			return;
		}
		m = grid.length;
		n = grid[0].length;
		visited = new boolean[m][n];
		int rest =0;
		for(int i=0;i<m;i++) {
			for(int j=0;j<m;j++) {
				if(grid[i][j]=='1'&&!visited[i][j]) {
					DFS(grid,i,j);
					rest++;
				}
			}
		}
		System.out.println(rest);
	}
	private static void DFS(char[][] grid, int x, int y) {
		// TODO Auto-generated method stub
		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]&&grid[newx][newy]=='1')
				DFS(grid,newx,newy);
		}
		
	}
	private static boolean inArea(int x, int y){
        return x >= 0 && x < m && y >= 0 && y < n;
    }
}

 

Classic Case

Given a two-dimensional matrix, containing  'X' , and  'O'( letter O ).

Find all the  'X' area around, and all of these areas  'O' with a  'X' filling.

Example:

X X X X
X O O X
X X O X
X O X X

After you run the function, the matrix becomes:

X X X X
X X X X
X X X X
X O X X

Explanation:

Surrounded interval does not exist on the boundary, in other words, on any boundary  'O' will not be filled  'X'. Not on any border, and on the boundary or not  'O' connected to  'O' eventually be filled  'X'. If two elements adjacent in the horizontal or vertical direction, they are called "connected" to.

 

This question we get basically can determine dfs, bfs traverse the title of the chart. He explained that the title will not be surrounded by a zone exists on the border, so we think o to special treatment on the boundary, as long as the replacement o special treatment on the boundary, then the rest o to x on it. Problems into how to find and border Unicom O , we need to consider the following.

X X X X
X O O X
X X O X
X O O X

This time o is not replaced. And because the border is connected. To record this state, we have in this case is replaced by o # as a placeholder, after completion of the search, replace encountered o x ( and does not communicate boundaries o ); # encountered, replacement back o ( and boundary communication O ).

How to find and border Unicom o?  From the border of diagrams dfs and bfs can be. Here a brief summary and next dfs dfs.

  • bfs recursion. Think about how the binary tree may be recursive traversal sequence.
  • bfs non-recursive. Usually a queue storage.
  • dfs recursion. The most commonly used as first-order binary tree traversal.
  • dfs non-recursive. Generally used stack.

So based on the above idea, we have four ways.

 

public class Reverse {
   static int d[][] = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
   static int m;
   static int n;
   static boolean[][] visited;
   static char[][] grid = {
           {'x','x','x','x'},
           {'x','0','0','x'},
           {'x','x','0','x'},
           {'x','0','x','x'}
       };
	public static void main(String[] args) {
		if(grid==null||grid.length==0||grid[0].length==0) {
			System.out.println(0);
			return;
		}
		m = grid.length;
		n = grid[0].length;
		visited = new boolean[m][n];
	
		for(int i=0;i<m;i++) {
			for(int j=0;j<m;j++) {
				boolean isEdge = i==0||j==0||i==m-1||j==n-1;
				if(isEdge&&grid[i][j]=='0') {
					DFS(grid,i,j);
			
				}
			}
		}
		for(int i = 0; i < m; i++) {
			for(int j = 0; j < n; j++) {
				if(grid[i][j] == '0') {
					grid[i][j] = 'x';
				}
				if(grid[i][j] == '#') {
					grid[i][j] = '0';
				}
			}
		}
	System.out.println(grid);
	}
	private static void DFS(char[][] grid, int i, int j) {
		// TODO Auto-generated method stub
		if(i<0||j<0||i>=grid.length||j>=grid[0].length||grid[i][j]=='x'||grid[i][j]=='#') {
			return;
		}
		grid[i][j]='#';
		DFS(grid, i-1, j);//上
		DFS(grid, i+1, j);//下
		DFS(grid, i, j-1);//左
		DFS(grid, i, j+1);//右
	}
	
}

Output:

 

Classic Case

N * N of the box, the horizontal line is completed with random matrix. Traces from top to bottom manner, the process of decline in a horizontal line across the apex of horizontal lines to another vertex. The bottom row of a lattice placed in a bomb, the bottom line can not put horizontal line, each line can be sequentially output by a plurality of horizontal lines across the serial bomber
input three parts, the first number, the second portion of the bomb that position of the last row position, the third part of the total number of horizontal lines, the fourth part of the bar, two vertices

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Huati {
    static int[] d = {1,0};//向下
    static int[][] Map;
    static int N;
    static int E;
    static int startIndex;
    static List<Integer> totallist;
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		while(scanner.hasNext()) {
			N = scanner.nextInt();
			E = scanner.nextInt();
			int M = scanner.nextInt();
			Map = new int[N][N];
			for(int j=0;j<M;j++) {
				int s1 = scanner.nextInt();
				int e1 = scanner.nextInt();
				int s2 = scanner.nextInt();
				int e2 = scanner.nextInt();
				Map[s1-1][e1-1] = j+1;
				Map[s2-1][e2-1] = j+1;
			}
			totallist = new ArrayList<Integer>();
			for(int i=0;i<N;i++) {
				startIndex = i;
				DFS(0,i);
			}
			Collections.sort(totallist);
			StringBuilder str = new StringBuilder();
			for(int i = 0;i<totallist.size();i++) {
				str.append((totallist.get(i)+1));
				if(i!=totallist.size()-1) {
					str.append(" ");
				}
			}
			System.out.println(str);
		}
	}

	private static void DFS(int x, int y) {
		// TODO Auto-generated method stub
		if(x==N-1&&y==(E-1)) {
			totallist.add(startIndex);
			return;
		}
		if(inArea(x+1,y)&&Map[x][y]==0) {
			DFS(x+1, y);
		}
		if(inArea(x, y)&&Map[x][y]!=0) {
			for(int i=0;i<Map[x].length;i++) {
				if(Map[x][i] == Map[x][y]&&i!=y) {
					if(inArea(x+1, y)) {
						DFS(x+1,i);
					}
					
				}
			}
		}
	}

	private static boolean inArea(int x, int y) {
		// TODO Auto-generated method stub
		return x>=0&&y>=0&&x<N&&y<N;
	}
}

 

Classic Case

Given a  m x n non-negative integer matrix represents the height of an individual cell on the mainland. "Pacific" in the left and on the border of the continent, and "Atlantic" in the right border of the continent and the lower boundary.

Only in accordance with a predetermined flow up, down, left, and right direction of the flow, or from high to low and can only flow in the same height.

Please identify those water can flow both to "Pacific", but also to coordinate the flow of "Atlantic" land unit.

 

prompt:

  1. Sequentially outputting coordinate important
  2. m  and  n  are less than 150

 

Example:

给定下面的 5x5 矩阵:

  太平洋 ~   ~   ~   ~   ~ 
       ~  1   2   2   3  (5) *
       ~  3   2   3  (4) (4) *
       ~  2   4  (5)  3   1  *
       ~ (6) (7)  1   4   5  *
       ~ (5)  1   1   2   4  *
          *   *   *   *   * 大西洋

返回:

[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (上图中带括号的单元).

Find the land from the sea, or too deep search of the point, there is too deep a point not to repeat the search on the line to find

This question is obviously able to get the first judge is subject of a two-dimensional plane backtracking algorithm, so we need to prepare a move coordinates:

# Respectively represent right lower left
self.directs = [(-1, 0) , (0, 1), (1, 0), (0, -1)]
a is determined whether the function is in the range:

in_area DEF (Self, the X-, the y-):
    return 0 <= the X-<self.m and 0 <= the y-<self.n
then continue the analysis, this question is to find a coordinate both to reach the Pacific Ocean can reach the Atlantic, but this process is generally not the first time the depth of the search can be completed, so we start from each boundary countercurrent search. Then recorded with a two-dimensional array is equivalent to four times the depth of search

import java.util.ArrayList;
import java.util.List; 

public class Ocean {

	public static void main(String[] args) {
		int[][] matrix= {{1,2,2,3,5},{3,2,3,4,4},{2,4,5,3,1},{6,7,1,4,5},{5,1,1,2,4}};
	    boolean[][] can1 = new boolean[matrix.length][matrix[0].length];//记录太平洋
	    boolean[][] can2 = new boolean[matrix.length][matrix[0].length];//记录大西洋
	    List<int[]> res = new ArrayList<>();
	    for(int i=0;i<matrix.length;i++) {//y固定x在变化
	    	DFS(can1,i,0,matrix); //y=0
	    	DFS(can2,i,matrix[0].length-1,matrix); //y=最大值
	    }
	    
	    for(int i=0;i<matrix[0].length;i++) {//x固定y在变化
	    	DFS(can1,0,i,matrix); //x=0
	    	DFS(can2,matrix.length-1,i,matrix); //x=最大值
	    }
	    for(int i=0;i<matrix.length;i++) {
	    	for(int j=0;j<matrix[0].length;j++) {
	    		if(can1[i][j]&&can2[i][j]) {
	    			res.add(new int[] {i,j});
	    		}
	    	}
	    }
	    System.out.println(res);
	}
	//(-1,0) 上  (0,1) 右 (1,0) 下  (0,-1)左
    private static int[] r= {-1,0,0,1};//上左右下
    private static int[] c= {0,-1,1,0};//上左右下
	private static void DFS(boolean[][] can, int i, int j, int[][] matrix) {
		// TODO Auto-generated method stub
		can[i][j] = true;
		for(int k=0;k<4;k++) {
			int ii = i+r[k];
			int jj = j+c[k];
			if(ii<0||jj<0||ii>=matrix.length||jj>=matrix[0].length||can[ii][jj]) {
				continue;
			}
			if(matrix[ii][jj]>=matrix[i][j]) {
				DFS(can,ii,jj,matrix);
			}
		}
		
	}
}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/qq_35029061/article/details/90746268