DFS三两道

1、LeetCode200. Number of Islands

Description:

Given a 2d grid map of '1's (land) and '0's (water), count the number of islands. An island is surrounded by water and is formed by connecting adjacent lands horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.

Example 1:

Input:
11110
11010
11000
00000
Output: 1

Example 2:

Input:
11000
11000
00100
00011
Output: 3

分析:

前后左右四个方位进行遍历计算,为了区别重复设置grid[r][c] = '0'。

代码如下:

public class Solution {

    private int m,n;
    private int[][] direction = {{1,0},{-1,0},{0,1},{0,-1}};
    public int numIslands(char[][] grid) {
        if (grid.length < 1 || grid[0].length < 1){
            return 0;
        }
        m = grid.length;
        n = grid[0].length;
        int cnt = 0;
        for (int i = 0; i < m; i++){
            for (int j = 0; j < n; j++){
                if(grid[i][j] == '1'){
                    dfs(grid, i, j);
                    cnt++;
                }
            }
        }
        return cnt;
    }

    private void dfs(char[][] grid, int r, int c){
        if (r < 0 || r >= m || c < 0 || c >= n || grid[r][c] == '0'){
            return;
        }
        grid[r][c] = '0';
        for (int[] dir : direction){
            dfs(grid, r + dir[0], c + dir[1]);
        }
    }
}

题目来源:https://leetcode.com/problems/number-of-islands/

2、LeetCode547. Friend Circles

Description:

There are N students in a class. Some of them are friends, while some are not. Their friendship is transitive in nature. For example, if A is a direct friend of B, and B is a direct friend of C, then A is an indirect friend of C. And we defined a friend circle is a group of students who are direct or indirect friends.

Given a N*N matrix M representing the friend relationship between students in the class. If M[i][j] = 1, then the ith and jth students are direct friends with each other, otherwise not. And you have to output the total number of friend circles among all the students.

Example 1:

Input: 
[[1,1,0],
 [1,1,0],
 [0,0,1]]
Output: 2
Explanation:The 0th and 1st students are direct friends, so they are in a friend circle. 
The 2nd student himself is in a friend circle. So return 2.

Example 2:

Input: 
[[1,1,0],
 [1,1,1],
 [0,1,1]]
Output: 1
Explanation:The 0th and 1st students are direct friends, the 1st and 2nd students are direct friends, 
so the 0th and 2nd students are indirect friends. All of them are in the same friend circle, so return 1.

Note:

  1. N is in range [1,200].
  2. M[i][i] = 1 for all students.
  3. If M[i][j] = 1, then M[j][i] = 1.

分析:

将好友关系看成是一个无向图,例如第 i 个人与第 j 个人是好友,那么 M[i][j] 和 M[j][i] 的值都为 1。

代码如下:

public class Solution {

    private int  n;
    public int findCircleNum(int[][] M) {
        if (M.length < 1 || M[0].length < 1){
            return 0;
        }
        n = M.length;
        int[] visited = new int[n+1];
        int count = 0;

        for (int i = 0; i < n; i++){
            if (visited[i] == 0){
                dfs(M, visited, i);
                count++;
            }
        }
        return count;
    }

    private void dfs(int[][] M, int[] visited, int i){
        visited[i] = 1;
        for (int j = 0; j < n; j++){
            if (M[i][j] == 1 && visited[j] == 0){
                dfs(M, visited, j);
            }
        }
    }
}

题目来源:https://leetcode.com/problems/friend-circles/description/

3、LeetCode130. Surrounded Regions

Description:

Given a 2D board containing 'X' and 'O' (the letter O), capture all regions surrounded by 'X'.

A region is captured by flipping all 'O's into 'X's in that surrounded region.

Example:

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

After running your function, the board should be:

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

Explanation:

Surrounded regions shouldn’t be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically.

分析:

使被 'X' 包围的 'O' 转换为 'X'。先填充最外侧,剩下的就是里侧了。

代码如下:

public class Solution {

    private int m,n;
    private int[][] direction = {{1,0},{-1,0},{0,1},{0,-1}};
    public void solve(char[][] board) {
        if (board.length < 1 || board[0].length < 1){
            return;
        }

        m = board.length;
        n = board[0].length;
        for (int i = 0; i < m; i++){
            dfs(board, i, 0);
            dfs(board, i, n - 1);
        }

        for (int j = 0; j < n; j++){
            dfs(board, 0, j);
            dfs(board, m-1, j);
        }

        for (int i = 0; i < m; i++){
            for (int j = 0; j < n; j++){
                if (board[i][j] == '*'){
                    board[i][j] = 'O';
                }else if (board[i][j] == 'O'){
                    board[i][j] = 'X';
                }
            }
        }
    }

    private void dfs(char[][] board, int r, int c){
        if (r < 0 || r >= m || c < 0 || c >=n || board[r][c] != 'O'){
            return;
        }
        board[r][c] = '*';
        for (int[] dir : direction){
            dfs(board, r+ dir[0], c + dir[1]);
        }
    }
}

题目来源:https://leetcode.com/problems/surrounded-regions/description/

4、LeetCode417. Pacific Atlantic Water Flow

Description:

Given an m x n matrix of non-negative integers representing the height of each unit cell in a continent, the "Pacific ocean" touches the left and top edges of the matrix and the "Atlantic ocean" touches the right and bottom edges.

Water can only flow in four directions (up, down, left, or right) from a cell to another one with height equal or lower.

Find the list of grid coordinates where water can flow to both the Pacific and Atlantic ocean.

Note:

  1. The order of returned grid coordinates does not matter.
  2. Both m and n are less than 150.

Example:

Given the following 5x5 matrix:

  Pacific ~   ~   ~   ~   ~ 
       ~  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  *
          *   *   *   *   * Atlantic

Return:

[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (positions with parentheses in above matrix).

分析:

       左边和上边是太平洋,右边和下边是大西洋,内部的数字代表海拔,海拔高的地方的水能够流到低的地方,求解水能够流到太平洋和大西洋的所有位置。

       直观上来看这道题目是需要以数组中的任意一个位置为起点,分别寻找一条数字由大到小并最终到达左上侧或是右下侧的路径。但是反过来来看,任意一个可以到达大西洋的水流必然会抵达数组左边和上边的任意一点。因此,我们可以以数组的边缘作为起点,寻找所有数字由小到大的路径,该路径上的所有点必然可以到达该边所在的洋流。

代码如下:

class Solution {
    private int r,c;
    private int[][] direction = {{1,0},{-1,0},{0,1},{0,-1}};
    private int[][] matrix;
    public List<List<Integer>> pacificAtlantic(int[][] matrix) {
        List<List<Integer>> lists = new ArrayList<>();
        if (matrix.length < 1 || matrix[0].length < 1){
            return lists;
        }

        r = matrix.length;
        c = matrix[0].length;
        this.matrix = matrix;
        //能够流入太平洋
        int[][] pacific = new int[r][c];
        //能够流入大西洋
        int[][] atlantic = new int[r][c];

        for (int i = 0; i < r; i++){
            //以左侧边为起点寻找可以流入太平洋的所有节点
            dfs(pacific, i, 0);
            //以右侧边为起点寻找可以流入大西洋的所有节点
            dfs(atlantic, i , c-1);
        }

        for (int j = 0; j < c; j++){
            //以上侧边为起点寻找可以流入太平的所有节点
            dfs(pacific, 0, j);
            //以下侧边为起点寻找可以流入大西洋的所有节点
            dfs(atlantic, r-1 , j);
        }

        for (int i = 0; i < r; i++){
            for (int j = 0; j < c; j++){
                //将即可以流入太平洋也可以流入大西洋的水域加入结果集
                if (pacific[i][j] == 1 && atlantic[i][j] == 1){
                    List<Integer> l = new ArrayList<>();
                    l.add(i);
                    l.add(j);
                    lists.add(l);
                }
            }
        }
        return lists;
    }

    private void dfs(int[][] canReach, int i, int j){
        if (1 == canReach[i][j]){
            return;
        }
        canReach[i][j] = 1;
        for (int[] dir : direction){
            int nextR = i + dir[0];
            int nextC = j + dir[1];
            if (nextR < 0 || nextR >= r || nextC < 0 || nextC >= c || matrix[i][j] > matrix[nextR][nextC]){
                continue;
            }
            dfs(canReach, nextR, nextC);
        }
    }
}

题目来源:https://leetcode.com/problems/pacific-atlantic-water-flow/description/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值