DFS

Copyright © 直通硅谷

http://www.zhitongguigu.com/

DFS

  • Depth First Search
  • One starts at the root (selecting some arbitrary node as the root in the case of a graph) and explores as far as possible along each branch before backtracking.

BFS

  • Breadth First Search
  • One starts at the root (selecting some arbitrary node as the root in the case of a graph) and explores the neighbor nodes first, before moving to the next level neighbors.

Searching Algorithm

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Problem

sub-Problem

sub-Problem

sub-Problem

sub-sub-Problem

sub-sub-Problem

sub-sub-sub-Problem

base-

problem

Depth First Search

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Search Order:

  • U, R, D, L
  • D, L, U, R

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Search Order:

  • U, R, D, L
  • D, L, U, R

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Problem

sub-Problem

sub-Problem

sub-Problem

sub-sub-Problem

sub-sub-Problem

Breadth First Search

sub-sub-Problem

sub-sub-Problem

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Search Order:

  • U, R, D, L
  • D, L, U, R

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Search Order:

  • U, R, D, L
  • D, L, U, R

Copyright © 直通硅谷

http://www.zhitongguigu.com/

A

/  \

B    C

/  \   /  \

D   E F   G

        /          \  

     H            I

  • Preorder Traversal
    • A B D E H C F G I
    • DFS Search Path
  • Level Order Traversal
    • A B C D E F G H I
    • BFS Search Path

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Tree Traversal

DFS Search Order:

U, R, D, L

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Filling the Grid

DFS Search Order:

U, R, D, L

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Filling the Grid

BFS Search Order:

U, R, D, L

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Filling the Grid

BFS Search Order:

U, R, D, L

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Filling the Grid

Use Case

DFS and BFS are both algorithms for searching TREE and GRAPH, but we will ONLY focus on trees, which is more common in interviews.

  • DFS
    • Recursion and backtrace
    • Stack
  • BFS
    • Find minimum path/distance/...
    • Queue

Copyright © 直通硅谷

http://www.zhitongguigu.com/

DFS

  • Most DFS related problems in interview is for trees.
    • Balanced Binary Tree
    • Symmetric Tree
    • Minimum Depth of Binary Tree
    • etc.
  • More general, most recursion problems are also DFS.
    • Permutation, Combination, Combination Sum.
    • Letter Combination of Phone Number, Generate Parenthesis.
    • Surrounded Regions, Word Search,

Copyright © 直通硅谷

http://www.zhitongguigu.com/

PreOrder Traversal

A

/  \

B    C

/  \   /  \

D   E F   G

        /          \  

     H            I

public void preOrder(TreeNode root) {
    if (root == null) {
        return;
    }
    // visit root
    preOrder(root.left);
    preOrder(root.right);
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Depth of Tree

Given a binary tree, calculate its depth.

1

2

3

Depth: 3

1

2

3

4

Depth: 4

3

2

3

3

4

1

2

3

4

2

Depth: 4

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Depth of Tree

Given a binary tree, calculate its depth.

public int depth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    return Math.max(depth(root.left), depth(root.right)) + 1;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Balanced Binary Tree

Given a binary tree, determine if it is height-balanced.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

1

2

2

3

3

4

4

False

1

2

3

4

True

3

2

3

3

4

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Balanced Binary Tree

Given a binary tree, determine if it is height-balanced.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

  • root is balanced
    • Diff(depth(root.left), depth(root.right)) <= 1
    • root.left is balanced && root.right is balanced.

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Balanced Binary Tree

Given a binary tree, determine if it is height-balanced.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

public boolean isBalanced(TreeNode root) {
    if (root == null)
        return true;
    if (Math.abs(getDepth(root.left) - getDepth(root.right)) > 1)
        return false;
    return isBalanced(root.left) && isBalanced(root.right);
}

int getDepth(TreeNode root) {
    if (root == null)
        return 0;
    return Math.max(getDepth(root.left), getDepth(root.right)) + 1;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Balanced Binary Tree

Given a binary tree, determine if it is height-balanced.

For this problem, a height-balanced binary tree is defined as a binary tree in which the depth of the two subtrees of every node never differ by more than 1.

public boolean isBalanced(TreeNode root) {
    return depth(root) != -1;
}

public int depth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    int leftDepth = depth(root.left);
    int rightDepth = depth(root.right);
    if (leftDepth == -1 || rightDepth == -1 ||
        Math.abs(leftDepth - rightDepth) > 1) {
        return -1;
    }
    return Math.max(leftDepth, rightDepth) + 1;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Symmetric Tree

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

    1
   / \
  2   2
 / \ / \
3  4 4  3

True

    1
   / \
  2   2
   \   \
   3    3

False

    1
   / \
  2   2
 / \ / \
4  3 4  3

False

    1
   / \
  2   2
 /     \
3       3

True

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Symmetric Tree

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

    1
   / \
  2   2
 / \ / \
3  4 4  3

True

    1
   / \
  2   2
   \   \
   3    3

False

  • Root is Symmetric
    • root.left is symmetric to root.right
  • A is symmetric to B
    • A.val == B.val
    • A.left is symmetric to B.right
    • A.right is symmetric to B.left

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Symmetric Tree

Given a binary tree, check whether it is a mirror of itself (ie, symmetric around its center).

public boolean isSymmetric(TreeNode root) {
    if (root == null) {
        return true;
    }
    return isSymmetric(root.left, root.right);
    
}
public boolean isSymmetric(TreeNode left, TreeNode right) {
    if (left == null && right == null) {
        return true;
    }
    if (left == null && right != null) {
        return false;
    }
    if (left != null && right == null) {
        return false;
    }
    if (left.val != right.val) {
        return false;
    }
    return isSymmetric(left.left, right.right)
        && isSymmetric(left.right, right.left);
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Minimum Depth of Binary Tree

Given a binary tree, find its minimum depth.

The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.

    1
   / \
  2   2
 / \ / \
3  4 4  3

3

    1
   / \
  2   2
 / \  
3  4   

2

    1
   / \
  2   2
 /     \
3       3

3

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Minimum Depth of Binary Tree

Given a binary tree, find its minimum depth.

The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.

  • Minimum depth of Root
    • if root is leaf, 1.
    • if root.left is null, return right + 1.
    • if root.right is null, return left + 1.
    • return the minimum of (left, right) + 1.

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Minimum Depth of Binary Tree

Given a binary tree, find its minimum depth.

The minimum depth is the number of nodes along the shortest path from the root node down to the nearest leaf node.

public int minDepth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    int leftDepth = minDepth(root.left);
    int rightDepth = minDepth(root.right);
    if (leftDepth == 0) {
        return rightDepth + 1;
    } else if (rightDepth == 0) {
        return leftDepth + 1;
    }
    return Math.min(leftDepth, rightDepth) + 1;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Path Sum

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.

      5
     / \
    4   8
   /   / \
  11  13  4
 /  \      \
7    2      1

22: [5, 4, 11, 2]

      3
     / \
    2   6
   /   / \
  9   22  9
 / \       \
7   2       1

31: [3, 6, 22]

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Path Sum

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.

      5
     / \
    4   8
   /   / \
  11  13  4
 /  \      \
7    2      1

22: [5, 4, 11, 2]

Knapsack: 

  • Except picking from all of numbers, only path from root to leaf is acceptable.
  • hasSum(TreeNode root, int sum)
    • Base case: root is leaf.
    • hasSum(root, sum) = hasSum(root.left, sum-root.val) || hasSum(root.right, sum-root.val)

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Path Sum

Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all the values along the path equals the given sum.

      5
     / \
    4   8
   /   / \
  11  13  4
 /  \      \
7    2      1

22: [5, 4, 11, 2]

public boolean hasPathSum(TreeNode root, int sum) {
    if (root == null) {
        return false;
    }
    if (root.left == null && root.right == null) {
        if (sum == root.val) {
            return true;
        }
        return false;
    }
    return hasPathSum(root.left, sum-root.val) || 
           hasPathSum(root.right, sum-root.val);
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Maximum Path Sum

Given a binary tree, find the maximum path sum.

For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path does not need to go through the root.

      5
     / \
    4   8
   /   / \
  11  13  4
 /  \      \
7    2      1

maxSum = 7 + 11 + 4 + 5 + 8 + 13 = 48

      5
     / \
    4   8
   /   / \
  11  13  4
 /  \      \
7    2      1

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Maximum Path Sum

Given a binary tree, find the maximum path sum.

For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path does not need to go through the root.

  5
 / \
-4 -8
  • Branch Sum (root):
    • Sum of nodes that end at root.
  • Maximum Path Sum (root):
    • root.val
    • root.val + maxbranchSum(root.left)
    • root.val + maxbranchSum(root.right)
    • root.val + maxbranchSum(root.left) + maxbranchSum(root.right)
  5
 / \
4  -8
  5
 / \
4   8
  5
 / \
-4  8

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Maximum Path Sum

Given a binary tree, find the maximum path sum.

For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path does not need to go through the root.

  • branchSum (root)
    • root.val
    • root.val + branchSum(root.left)
    • root.val + branchSum(root.right)

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Maximum Path Sum

Given a binary tree, find the maximum path sum.

For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path does not need to go through the root.

public static int maxBranchSum(TreeNode root) {
    if (root == null) {
        return 0;
    }
    int leftSum = maxBranchSum(root.left);
    int rightSum = maxBranchSum(root.right);
    int branchMaxSum = root.val + Math.max(0, Math.max(leftSum, rightSum));
    return branchMaxSum;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Maximum Path Sum

Given a binary tree, find the maximum path sum.

For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path does not need to go through the root.

static int max_sum = Integer.MIN_VALUE;

public static int maxPathSum(TreeNode root) {
    if (root == null)
        return 0;
    max_sum = Integer.MIN_VALUE;
    maxBranchSum(root);
    return max_sum;
}

public static int maxBranchSum(TreeNode root) {
    if (root == null) {
        return 0;
    }
    int leftSum = maxBranchSum(root.left);
    int rightSum = maxBranchSum(root.right);
    int branchMaxSum = root.val + Math.max(0, Math.max(leftSum, rightSum));
    max_sum = Math.max(max_sum, 
                       Math.max(branchMaxSum, leftSum + root.val + rightSum));
    return branchMaxSum;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Maximum Path Sum

Given a binary tree, find the maximum path sum.

For this problem, a path is defined as any sequence of nodes from some starting node to any node in the tree along the parent-child connections. The path does not need to go through the root.

public static int maxPathSum(TreeNode root) {
    if (root == null)
        return 0;
    int[] max = {Integer.MIN_VALUE};
    maxBranchSum(root, max);
    return max[0];
}

public static int maxBranchSum(TreeNode root, int[] max) {
    if (root == null) {
        return 0;
    }
    int leftSum = maxBranchSum(root.left, max);
    int rightSum = maxBranchSum(root.right, max);
    int branchMaxSum = root.val + Math.max(0, Math.max(leftSum, rightSum));
    max[0] = Math.max(max[0], Math.max(branchMaxSum, leftSum + root.val + rightSum));
    
    return branchMaxSum;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

DFS for Trees

  • Complete Search
    • If you need to traverse all the nodes in the tree.
    • No need for minimum/shortest/... depth, etc.
  • Normal Recursion
    • Tree is recursive definition,  so applying recursion on trees are very direct and easy understanding
    • Sub-problem
    • Base case
    • Recursion rule
    • ALWAYS think about two branches (left and right), pseudo code is helpful.

Copyright © 直通硅谷

http://www.zhitongguigu.com/

More general DFS

  • One Dimension
    • Letter Combination of Phone Number
    • Generate Parenthesis
    • Palindrome Partitioning
    • etc.
  • Two Dimensions
    • Maze
    • N Queens
    • Word Search
    • etc.

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Search

Given a 2D board and a word, find if the word exists in the grid.

The word can be constructed from letters of sequentially adjacent cell, where "adjacent" cells are those horizontally or vertically neighboring. The same letter cell may not be used more than once.

For example, given a board,

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

word = "ABCCED", -> returns true,
word = "SEE", -> returns true,
word = "ABCB", -> returns false.

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Search

public boolean exist(char[][] board, String word) {
    if (board.length == 0 || board[0].length == 0)
        return false;
    boolean[][] flag = new boolean[board.length][board[0].length];
    for (int i = 0; i < board.length; i++) {
       Arrays.fill(flag[i], false);
    }
    for (int i = 0; i < board.length; i++) {
        for (int j = 0; j < board[0].length; j++) {
            if (exist(board, i, j, word, 0, flag))
                return true;
        }
    }
    return false;
}
public boolean exist(char[][] board, int x, int y, String word, int index,
                     boolean[][] flag) {
    if (index == word.length())
        return true;
    if (x < 0 || y < 0 || x >= board.length || y >= board[0].length
        || flag[x][y] || board[x][y] != word.charAt(index))
        return false;
    int[] dx = {1, 0, -1, 0};
    int[] dy = {0, 1, 0, -1};
    for (int i = 0; i < 4; i++) {
        flag[x][y] = true;
        if (exist(board, x+dx[i], y+dy[i], word, index+1, flag))
            return true;
        flag[x][y] = false;
    }
    return false;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Palindrome Partitioning

Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.
 
Example:
Input: "aab"
Output: [ ["aa", "b"], ["a", "a", "b"] ]

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Given a string s, partition s such that every substring of the partition is a palindrome.
Return all possible palindrome partitioning of s.

 

  • Try substring from the beginning.
    • If it's palindrome, then palindrome partition the left part and merge the results.

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Palindrome Partitioning

Palindrome Partitioning

public List<List<String>> partition(String s) {
    List<List<String>> results = new ArrayList<>();
    partition(results, s, 0, new ArrayList<String>());
    return results;
}

public void partition(List<List<String>> results, String s, int start,
                      List<String> path) {
    if (start == s.length()) {
        results.add(new ArrayList<>(path));
        return;
    }
    for (int i = start + 1; i <= s.length(); i++) {
        String sub = s.substring(start, i);
        if (isPalindrome(sub)) {
            path.add(sub);
            partition(results, s, i, path);
            path.remove(path.size() - 1);
        }
    }
}

public boolean isPalindrome(String s) {
    for (int i = 0, j = s.length()-1; i < j; i++, j--) {
        if (s.charAt(i) != s.charAt(j))
            return false;
    }
    return true;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

General DFS

  • Depth First Search
  • Search solutions from the whole possible search space
  • Search is a process of trying and backtracking
  • Pruning is important

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Homework

Same Tree

Validate Binary Search Tree

Flatten Binary Tree to Linked List

Path Sum II

Course Schedule

Tree Traversal: 

    Preorder Traversal 

    Inorder Traversal (sort tree) 

     PostorderTraversal 

     Method: 

         recursion( DFS) 

         iteration (Stack) 

Copyright © 直通硅谷

http://www.zhitongguigu.com/

[GoValley-201612] DFS

By govalley201612

[GoValley-201612] DFS

  • 679