leetcode练习
200. 岛屿数量
题目
这道题是一道简单的深搜题,首先双层遍历找到第一个’1’所在的位置,岛屿数加1,然后开始深搜,并将所有走过的地方标位’0’,以此类推,直到所有的位置都为’0’。
public int numIslands(char[][] grid) {
if (grid == null || grid.length == 0) {
return 0;
}
int count = 0;
for (int i = 0; i < grid.length; i++){
for (int j = 0; j < grid[0].length; j++){
if(grid[i][j] == '1'){
count++;
dfs(i, j, grid);
}
}
}
return count;
}
public void dfs(int i, int j, char[][] grid){
if (i < 0 || i >= grid.length || j < 0 || j >= grid[0].length || grid[i][j] == '0') return;
grid[i][j] = '0';
dfs(i - 1, j, grid);
dfs(i + 1, j, grid);
dfs(i, j - 1, grid);
dfs(i, j + 1, grid);
}
广搜的思想也很简单,找到第一个’1’入队列,并将值改为’0’,每次将距离为1的四个方向的’1’入队,以此类推直到队列为空。
public int numIslands1(char[][] grid){
int count = 0;
int[][] vector = new int[][]{{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
Queue<int[]> queue = new LinkedList<>();
for (int i = 0; i < grid.length; i++){
for (int j = 0; j < grid[0].length; j++){
if(grid[i][j] == '1'){
count++;
grid[i][j] = '0';
queue.add(new int[]{i, j});
while(!queue.isEmpty()){
int[] n = queue.poll();
for (int[] v : vector) {
int nr = n[0] + v[0];
int nc = n[1] + v[1];
if (nr >= 0 && nc >= 0 && nr < grid.length && nc < grid[0].length && grid[nr][nc] == '1') {
grid[nr][nc] = '0';
queue.add(new int[]{nr, nc});
}
}
}
}
}
}
return count;
}
547. 省份数量**
题目
深度遍历DFS,设置一个visited记录数组,每次跳到连通城市,找还没有访问过的城市。A-B,B-C, A-D 优先往下找。
public int findCircleNum(int[][] isConnected) {
int provinces = isConnected.length;
boolean[] visited = new boolean[provinces];
int circles = 0;
for (int i = 0; i < provinces; i++) {
if (!visited[i]) {
dfs(isConnected, visited, provinces, i);
circles++;
}
}
return circles;
}
public void dfs(int[][] isConnected, boolean[] visited, int provinces, int i) {
for (int j = 0; j < provinces; j++) {
if (isConnected[i][j] == 1 && !visited[j]) {
visited[j] = true;
dfs(isConnected, visited, provinces, j);
}
}
}
广度遍历,优先找A的所有连通城市,再找连通城市的其他连通城市。主要思想都是设置一个visited函数。
public int findCircleNum1(int[][] isConnected) {
int provinces = isConnected.length;
boolean[] visited = new boolean[provinces];
int circles = 0;
Queue<Integer> queue = new LinkedList<Integer>();
for (int i = 0; i < provinces; i++) {
if (!visited[i]) {
queue.offer(i);
while (!queue.isEmpty()) {
int j = queue.poll();
visited[j] = true;
for (int k = 0; k < provinces; k++) {
if (isConnected[j][k] == 1 && !visited[k]) {
queue.offer(k);
}
}
}
circles++;
}
}
return circles;
}
并查集,find和union函数可以当做模板背诵。
public int findCircleNum2(int[][] isConnected) {
int provinces = isConnected.length;
int[] parent = new int[provinces];
for (int i = 0; i < provinces; i++) {
parent[i] = i;
}
for (int i = 0; i < provinces; i++) {
for (int j = i + 1; j < provinces; j++) {
if (isConnected[i][j] == 1) {
union(parent, i, j);
}
}
}
int circles = 0;
for (int i = 0; i < provinces; i++) {
if (parent[i] == i) {
circles++;
}
}
return circles;
}
//让index1的父节点指向index2的父节点
public void union(int[] parent, int index1, int index2) {
parent[find(parent, index1)] = find(parent, index2);
}
public int find(int[] parent, int index) {
//不是父节点,找父节点
if (parent[index] != index) {
parent[index] = find(parent, parent[index]);
}
return parent[index];
}