分析岛屿问题
LeetCode200(岛屿数量)
思想:深度优先遍历
class Solution { /*****定义全局变量*****/ //方向数组,当前位置上、下、左、右4个方向的 坐标 static final int[][] direction = {{-1,0},{1,0},{0,-1},{0,1}}; int row; //行数 int clown;//列数 //标记数组,标记grid坐标对应位置是否被访问过 boolean[][] flag; public int numIslands(char[][] grid) { row = grid.length; if(row == 0) return 0; clown = grid[0].length; flag = new boolean[row][clown]; //记录岛屿数量 int count = 0; for(int i = 0; i < row; i++){ for(int j = 0; j < clown; j++){ //如果是陆地,并且没有被访问过,就进行深度优先遍历 if(grid[i][j] == '1' && !flag[i][j]){ count++; dfs(grid,i,j); } } } return count; } // 从坐标为 (i,j) 的点开始进行深度优先遍历 public void dfs(char[][] grid,int i, int j) { flag[i][j] = true; //递归遍历4个方向 for(int k = 0; k < 4; k++){ int newX = i + direction[k][0]; int newY = j + direction[k][1]; //如果不越界、没有被访问过、并且是陆地, if(newX >= 0 && newX < row && newY >= 0 && newY < clown && !flag[newX][newY] && grid[newX][newY] == '1'){ //递归 dfs(grid,newX, newY); } } } }
拓展(字节跳动笔试)
世界杯开幕式会在球场C举行,球场C的球迷看台可以容纳M*N个球迷。在球场售票完成后,现官方想统计此次开幕式一共有多少个球队球迷群体,最大的球队球迷群体有多少人。
经调研发现,球迷群体在选座时有以下特性:
同球队的球迷群体会选择相邻座位,不同球队的球迷群体会选择不相邻的座位(注解:相邻包括前后相邻,左右相邻,斜对角相邻)
给定一个M*N的二维球场,0代表该位置没有坐人,1代表该位置已有选择,希望输出球队群体个数P,最大的球队群体人数Q
输入描述:
第一行,2个数字,M及N,使用英文逗号分隔
接下来M行,每行N的数字,使用英文逗号分隔
输出描述:
一行,2个数字,P及Q,使用英文逗号分隔
其中P表示球队群体个数,Q表示最大的球队群体人数
示例:
输入
10,10
0,0,0,0,0,0,0,0,0,0
0,0,0,1,1,0,1,0,0,0
0,1,0,0,0,0,0,1,0,1
1,0,0,0,0,0,0,0,1,1
0,0,0,1,1,1,0,0,0,1
0,0,0,0,0,0,1,0,1,1
0,1,1,0,0,0,0,0,0,0
0,0,0,1,0,1,0,0,0,0
0,0,1,0,0,1,0,0,0,0
0,1,0,0,0,0,0,0,0,0
输出:6,8
代码:
import java.util.Scanner; public class Main{ /***定义全局变量***/ public static int row,clown; public static int[][] nums; public static int maxNum;//最大的球队群体人数 public static int nstep;//记录一个球队的人数 ///标记数组,标记nums坐标对应位置是否被访问过 public static boolean[][] visited; //方向数组:当前位置的上下左右斜对角 public static final int[][] direction = {{-1,0},{1,0},{0,-1},{0,1},{-1,-1},{-1,1},{1,-1},{1,1}}; public static void main(String[] args) { Scanner sc = new Scanner(System.in); while(sc.hasNext()){ String[] rangArr = sc.next().split(","); //行数 row = Integer.parseInt(rangArr[0]); //列数 clown = Integer.parseInt(rangArr[1]); nums = new int[row][clown]; visited = new boolean[row][clown]; //读取nums的值 for(int i = 0; i < row; i++){ String[] tempArr = sc.next().split(","); for(int j = 0; j < clown; j++){ nums[i][j] = Integer.parseInt(tempArr[j]); } } //球队群体个数 int count = 0; //初始化最大的球队群体人数 maxNum = 0; //遍历 for(int i = 0; i < row; i++){ for(int j = 0; j < clown; j++){ //如果是球迷,并且没有被访问过,就进行深度优先遍历 if(nums[i][j] == 1 && !visited[i][j]){ dfs(i, j, 0); count++; } } } System.out.println(count + "," + maxNum); } } // 从坐标为 (i,j) 的点开始进行深度优先遍历,注意还要求最大的球迷群体的人的个数 public static void dfs(int i, int j, int steps){ if(steps == 0) nstep = 0; visited[i][j] = true; nstep++; //依次遍历8个方向 for(int k = 0; k < direction.length; k++){ int newX = i + direction[k][0]; int newY = j + direction[k][1]; //如果没有越界并且是球迷并且没有被访问过: if(newX >= 0 && newX <row && newY >= 0 && newY < clown && !visited[newX][newY] && nums[newX][newY] == 1){ dfs(newX, newY, steps + 1); } } maxNum = Math.max(maxNum, nstep); } }