Stack and depth-first search (DFS)


And BFSsimilarly, the depth-first search (DFS)for another important algorithms / search tree traversal / FIG. You can also use the more abstract scene.

Traversing the tree, as mentioned, we can use DFSfor order traversal , in order traversal and postorder traversals . There is a common denominator in all three traversal order: Unless we reach the deepest node, otherwise we will never go back .

It is also DFSand BFSthe biggest difference between, BFSis never explored in depth, unless it has access to all the levels in the current node .

stencil

Recursive Template

There are two implementation DFSmethods. The first method is recursive:

boolean DFS(Node cur, Node target, Set<Node> visited) {
    return true if cur is target;
    for (next : each neighbor of cur) {
        if (next is not in visited) {
            add next to visted;
            return true if DFS(next, target, visited) == true;
        }
    }
    return false;
}

When we realize recursively DFStime, it does not seem to use any stack. But in fact, we are using the implicit stack provided by the system, also known as the call stack (Call Stack).

Explicit stack template

Advantage recursive solution is that it is easier to implement. However, there is one big disadvantage: if the depth of recursion is too high, you will suffer a stack overflow. In this case, you might want to use BFS, or use explicit stack to achieve DFS.

boolean DFS(int root, int target) {
    Set<Node> visited;
    Stack<Node> s;
    add root to s;
    while (s is not empty) {
        Node cur = the top element in s;
        return true if cur is target;
        for (Node next : the neighbors of cur) {
            if (next is not in visited) {
                add next to s;
                add next to visited;
            }
        }
        remove cur from s;
    }
    return false;
}

example

1. Number of islands

  • Difficulty:Medium

Title Description

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:

Input:
11110
11010
11000
00000
Output: 1

Example 2:

Input:
11000
11000
00100
00011
Output: 3

Problem-solving ideas and achieve

I was in this article shows how to use in BFSsolving this question, the fact that the problem using DFSsimpler, because the former also need to maintain a queue breadth-first search hierarchy information during the search.

Use DFSproblem-solving as follows:

public class B200NumIslands {

    public int numIslands(char[][] grid) {
        int nr = grid.length;
        if (nr == 0) return 0;
        int nc = grid[0].length;
        if (nc == 0) return 0;

        int result = 0;

        for (int r = 0; r < nr; r++) {
            for (int c = 0; c < nc; c++) {
                if (grid[r][c] == '1') {
                    result++;
                    dfs(grid, r, c);
                }
            }
        }

        return result;
    }

    private void dfs(char[][] grid, int r, int c) {
        int nr = grid.length;
        int nc = grid[0].length;

        // 排除边界外的情况
        if (r >= nr || c >= nc || r < 0 || c < 0) return;
        // 排除边界外指定位置为 '0' 的情况
        if (grid[r][c] == '0') return;

        // 该位置为一个岛,标记为已探索
        grid[r][c] = '0';

        dfs(grid, r - 1, c);  // top
        dfs(grid, r + 1, c);  // bottom
        dfs(grid, r, c - 1);  // left
        dfs(grid, r, c + 1);  // right
    }
}

2. FIG Cloning

  • Difficulty:Medium

Title Description

You undirected communication reference a node diagram, you return to this figure deep copy (clone) .

Each node in the graph it contains a value val(int)list of its neighbors ( list[Node]).

class Node {
    public int val;
    public List<Node> neighbors;
}

A more detailed description with reference to the subject herein :
https://leetcode-cn.com/problems/clone-graph/

Problem-solving ideas and achieve

Title more difficult to understand, be noted that:

  1. Because deep copy , all nodes need to newbe instantiated, i.e., the need to traverse each node in the graph, so it emerges out of the solution, the use DFSor BFScan;
  2. Each node has copied are marked to avoid an infinite loop causes a stack overflow.

With DFScodes are as follows:

class Solution {
    public Node cloneGraph(Node node) {
        HashMap<Node,Node> map = new HashMap<>();
        return dfs(node, map);
    }

    private Node dfs(Node root, HashMap<Node,Node> map) {
        if (root == null) return null;
        if (map.containsKey(root)) return map.get(root);

        Node clone = new Node(root.val, new ArrayList());
        map.put(root, clone);
        for (Node nei: root.neighbors) {
            clone.neighbors.add(dfs(nei, map));
        }
        return clone;
    }
}

3. Objectives and

  • Difficulty:Medium

Title Description

Given an array of non-negative integer, a1, a2, ..., an , and a number of goals, S. Now you have two symbols + and -. For any integer array, you can from +or -to select a symbol added earlier.

And the final array can return all the way to add the number of symbols is the target number of S.

Example 1:

输入: nums: [1, 1, 1, 1, 1], S: 3
输出: 5
解释:

>-1+1+1+1+1 = 3
+1-1+1+1+1 = 3
+1+1-1+1+1 = 3
+1+1+1-1+1 = 3
+1+1+1+1-1 = 3

一共有5种方法让最终目标和为3。

note:

1. non-empty array, and a length of no more than 20.
2. The initial array and not more than 1,000.
3. the end result is returned be able to save 32-bit integer.

Problem-solving ideas and achieve

To be honest I did not expect this question to use DFSviolence to resolve, or too little experience, violent solution of this question is entirely possible, and does not time out, as the title says the array length does not exceed 20, 20-digit sequence , Cheng Si also combinations 2^20combinations:

public class Solution {

    int count = 0;

    public int findTargetSumWays(int[] nums, int S) {
        dfs(nums, 0, 0, S);
        return count;
    }

    private void dfs(int[] nums, int index, int sum, int S) {
        if (index == nums.length) {
            if (sum == S) count++;
        } else {
            dfs(nums, index + 1, sum + nums[index], S);
            dfs(nums, index + 1, sum - nums[index], S);
        }
    }
}

4. The binary tree preorder

  • Difficulty:Medium

Title Description

Given a binary tree in preorder to return it.

Advanced : recursive algorithm is very simple, you can do it through an iterative algorithm?

Problem-solving ideas and achieve

Binary Tree is really very interesting correlation algorithm knowledge of a point (because this question is very typical, I think the highest probability test to interview 2333 ...), I would follow a more detailed inquiry for this knowledge, this article lists Both solutions.

1. recursion

public class Solution {

  // 1.递归法
  public List<Integer> inorderTraversal(TreeNode root) {
      List<Integer> list = new ArrayList<>();
      dfs(root, list);
      return list;
  }

  private void dfs(TreeNode node, List<Integer> list) {
      if (node == null) return;

      // 中序遍历:左中右
      if (node.left != null)
          dfs(node.left, list);

      list.add(node.val);

      if (node.right != null)
          dfs(node.right, list);
  }
}

2. Stack

public class Solution {

  // 2.使用栈
  public List<Integer> inorderTraversal(TreeNode root) {
        List<Integer> list = new ArrayList<>();
        Stack<TreeNode> stack = new Stack<>();

        TreeNode curr = root;
        while (!stack.isEmpty() || curr != null) {
            while (curr != null) {
                stack.push(curr);
                curr = curr.left;
            }
            curr = stack.pop();
            list.add(curr.val);
            curr = curr.right;
        }
        return list;
    }
}

Reference & thanks

Most of excerpts from the article LeetCode, stack and depth-first search Overview:

  • https://leetcode-cn.com/explore/learn/card/queue-stack/219/stack-and-dfs/

example:

  • https://leetcode-cn.com/problems/number-of-islands
  • https://leetcode-cn.com/problems/clone-graph/
  • https://leetcode-cn.com/problems/target-sum/
  • https://leetcode-cn.com/problems/binary-tree-inorder-traversal/

about me

Hello, I am confused Qing Mei sniff , if you think the article valuable to you, welcome ❤️, also welcomed the attention to my blog or GitHub .

If you think the article is even worse so something, please also focus on urging me to write a better article - if one day I progress of it?

Published 99 original articles · won praise 396 · views 470 000 +

Guess you like

Origin blog.csdn.net/mq2553299/article/details/104304567