BFS

Copyright © 直通硅谷

http://www.zhitongguigu.com/

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.
  • Find minimum path/distance/...
    • Minimum Tree Depth
    • Word Edit Distance
    • etc...
  • No Recursion, QUEUE

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Queue in Java

  • Queue<> queue = new LinkedList<>();
    • boolean offer(Element e); (add)
      • offer can return false while add can only cause exception when the element cannot be added due to capacity restriction.
    • Element poll(); (remove)
      • poll returns null when empty while remove will throw exception.
    • Element peek(); (element)
      • peek returns null when empty while element will throw exception.

Copyright © 直通硅谷

http://www.zhitongguigu.com/

BFS for Binary Trees

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Level Order Traversal

A

/  \

B    C

/  \   /  \

D   E F   G

        /          \  

     H            I

while (level != end) {

    visit (level);

    level++;

}

How to visit the next level? How to know what next level is?

Put the child nodes into queue while visiting a certain line.

Given a binary tree, return its level order traversal.

A, B, C, D, E, F, G, H, I

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Level Order Traversal

A

/  \

B    C

/  \   /  \

D   E F   G

        /          \  

     H            I

Queue<TreeNode> queue = new LinkedList<>();

queue.offer(root);

while (!queue.isEmpty()) {

    Queue<TreeNode> queue2 = new LinkedList<>();

    while (!queue.isEmpty()) {

        TreeNode top = queue.poll();

        // visit top.

        if (top.left != null) queue2.offer(top.left);

        if (top.right != null) queue2.offer(top.right);

    }

    queue = queue2;

}

Given a binary tree, return its level order traversal.

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Level Order Traversal

A

/  \

B    C

/  \   /  \

D   E F   G

        /          \  

     H            I

Queue<TreeNode> queue = new LinkedList<>();

queue.offer(root);

queue.offer(null);

while (!queue.isEmpty()) {

    TreeNode top = queue.poll();

    if (top == null) {

        // do something to the current level.

        queue.offer(null);

    } else {

        // visit top.

       if (top.left != null) queue.offer(top.left);

       if (top.right != null) queue.offer(top.right);

    }

}

Given a binary tree, return its level order traversal.

Dummy Node

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Level Order Traversal

A

/  \

B    C

/  \   /  \

D   E F   G

        /          \  

     H            I

Queue<TreeNode> queue = new LinkedList<>();

queue.offer(root);

while (!queue.isEmpty()) {

    TreeNode top = queue.poll();

    // visit top.

    if (top.left != null) {

        queue.offer(top.left);

    }

    if (top.right != null) {

        queue.offer(top.right);

    }

}

Given a binary tree, return its level order traversal.

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Level Order Traversal

Given a binary tree, return its level order traversal.

    3
   / \
  9  20
    /  \
   15   7
[
  [3],
  [9,20],
  [15,7]
]

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Level Order Traversal

Given a binary tree, return its level order traversal.

public List<List<Integer>> levelOrder(TreeNode root) {
    List<List<Integer>> results = new ArrayList<>();
    Queue<TreeNode> queue = new LinkedList<>();
    if (root != null) {
        queue.offer(root);
    }
    while (!queue.isEmpty()) {
        List<Integer> oneResult = new ArrayList<>();
        Queue<TreeNode> queue2 = new LinkedList<>();
        while (!queue.isEmpty()) {
            TreeNode top = queue.poll();
            if (top.left != null) {
                queue2.offer(top.left); 
            }
            if (top.right != null) {
                queue2.offer(top.right);
            }
            oneResult.add(top.val);
        }
        results.add(oneResult);
        queue = queue2;
    }
    return results;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Zigzag Level Order Traversal

Given a binary tree, return its zigzag level order traversal.

    3
   / \
  9  20
    /  \
   15   7
[
  [3],
  [20,9],
  [15,7]
]

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Zigzag Level Order Traversal

public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
    List<List<Integer>> results = new ArrayList<>();
    Queue<TreeNode> queue = new LinkedList<>();
    if (root != null) {
        queue.offer(root);
    }
    boolean isLeft = true;
    while (!queue.isEmpty()) {
        List<Integer> oneResult = new ArrayList<>();
        Queue<TreeNode> queue2 = new LinkedList<>();
        while (!queue.isEmpty()) {
            TreeNode top = queue.poll();
            if (top.left != null) {
                queue2.offer(top.left); 
            }
            if (top.right != null) {
                queue2.offer(top.right);
            }
            oneResult.add(top.val);
        }
        if (!isLeft) {
            Collections.reverse(oneResult);
        }
        results.add(oneResult);
        isLeft = !isLeft;
        queue = queue2;
    }
    return results;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Binary Tree Zigzag Level Order Traversal

  • Reversing an ArrayList for every loop is time consuming.
  • Visit order is opposite from level to level
    • FILO
    • Stack

Copyright © 直通硅谷

http://www.zhitongguigu.com/

public List<List<Integer>> zigzagLevelOrder(TreeNode root) {
    List<List<Integer>> results = new ArrayList<>();
    if (root == null)
        return results;
    Stack<TreeNode> stack = new Stack<>();
    stack.push(root);
    boolean left = true;
    while (!stack.isEmpty()) {
        List<Integer> oneResult = new ArrayList<>();
        Stack<TreeNode> stack2 = new Stack<>();
        while (!stack.isEmpty()) {
            TreeNode top = stack.pop();
            if (!left) {
                if (top.right != null)
                    stack2.push(top.right);
                if (top.left != null)
                    stack2.push(top.left);
            } else {
                if (top.left != null)
                    stack2.push(top.left);
                if (top.right != null)
                    stack2.push(top.right);
            }
            oneResult.add(top.val);
        }
        results.add(oneResult);
        stack = stack2;
        left = !left;
    }
    return results;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

How to level order traverse

  • If level is important, most cases
    • Two queues.
    • Dummy node, different from all other nodes to be a flag.
    • Maintain size of current level.
  • If level is unimportant
    • One queue.

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
    1
   / \
  2   2
 / \  
3  4   
    1
   / \
  2   2
 /     \
3       3

3

2

3

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Minimum Depth of Binary Tree

DFS

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

Copyright © 直通硅谷

http://www.zhitongguigu.com/

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 Binary Tree

BFS

  • Level Traverse the tree, return the depth of the first leaf node.

Copyright © 直通硅谷

http://www.zhitongguigu.com/

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 Binary Tree

public int minDepth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    Queue<TreeNode> queue = new LinkedList<TreeNode>();
    queue.offer(root);
    queue.offer(null);
    int minDepth = 1;
    while (!queue.isEmpty()) {
        TreeNode top = queue.poll();
        if (top == null) {
            minDepth++;
            queue.offer(null);
            continue;
        }
        if (top.left == null && top.right == null) {
            return minDepth;
        }
        if (top.left != null) {
            queue.offer(top.left);
        }
        if (top.right != null) {
            queue.offer(top.right);
        }
    }
    return minDepth;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Minimum Depth of Binary Tree

public int minDepth(TreeNode root) {
    if (root == null) {
        return 0;
    }
    Queue<TreeNode> queue = new LinkedList<TreeNode>();
    queue.offer(root);
    int minDepth = 1;
    while (!queue.isEmpty()) {
        Queue<TreeNode> queue2 = new LinkedList<TreeNode>();
        while (!queue.isEmpty()) {
            TreeNode top = queue.poll();
            if (top.left == null && top.right == null) {
                return minDepth;
            }
            if (top.left != null) {
                queue2.offer(top.left);
            }
            if (top.right != null) {
                queue2.offer(top.right);
            }
        }
        minDepth++;
        queue = queue2;
    }
    return minDepth;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

  • Level is important, most cases
    • Two queues.
    • Dummy node, different from all other nodes to be a flag.
    • Maintain size of current level.
  • Level is unimportant
    • One queue.
  • Don't add null (except dummy) into queues.
  • Left/Right null pointer check.

BFS for Binary Trees

Copyright © 直通硅谷

http://www.zhitongguigu.com/

BFS for Word Distance

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Given two words (beginWord and endWord), and a dictionary's word list, find the length of shortest transformation sequence from beginWord to endWord, such that:

  • Only one letter can be changed at a time
  • Each intermediate word must exist in the word list

 

For example,
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

As one shortest transformation is "hit" -> "hot" -> "dot" -> "dog" -> "cog",
return its length 5.

 

Note:

  • Return 0 if there is no such transformation sequence.
  • All words have the same length.
  • All words contain only lowercase alphabetic characters.

Word Ladder

Copyright © 直通硅谷

http://www.zhitongguigu.com/

DFS

  • begin: hot, end: hip, list: [hog, hig, dig, dip, hip, hit]
  • hot -> hog -> hig -> dig -> dip -> hip
  • Much deeper than needed, time consuming.
  • Error prone.

BFS

  • Keep a set of all words that can be transformed to.
  • Put all words with 1 edit distance into the set every time.
  • When the end word is met, then the minimum distance is found.

Word Ladder

Copyright © 直通硅谷

http://www.zhitongguigu.com/

  • BFS
    • Keep a set of all words that can be transformed to.
    • Put all words with 1 edit distance into the set every time.
    • When the end word is met, then the minimum distance is found.

Word Ladder

beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

hit

Copyright © 直通硅谷

http://www.zhitongguigu.com/

  • BFS
    • Keep a set of all words that can be transformed to.
    • Put all words with 1 edit distance into the set every time.
    • When the end word is added, then the minimum distance is found.

Word Ladder

beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

hit

hot

Copyright © 直通硅谷

http://www.zhitongguigu.com/

  • BFS
    • Keep a set of all words that can be transformed to.
    • Put all words with 1 edit distance into the set every time.
    • When the end word is added, then the minimum distance is found.

Word Ladder

beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

hit

hot

dot

lot

Copyright © 直通硅谷

http://www.zhitongguigu.com/

  • BFS
    • Keep a set of all words that can be transformed to.
    • Put all words with 1 edit distance into the set every time.
    • When the end word is added, then the minimum distance is found.

Word Ladder

beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

hit

hot

dot

lot

dog

log

Copyright © 直通硅谷

http://www.zhitongguigu.com/

  • BFS
    • Keep a set of all words that can be transformed to.
    • Put all words with 1 edit distance into the set every time.
    • When the end word is added, then the minimum distance is found.

Word Ladder

beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

hit

hot

dot

lot

dog

log

cog

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder

transformed_words <- beginWord

while (transformed_words is not empty) {

    for (word_b in transformed_words) {

        if (endWord is within 1 distance) {

            return distance

        }

        if (some word in dict is within 1 distance

             && it is not in transformed_words) {

            transformed_words.add(word)

        }

    }

    update distance

}

return 0

How to check?

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder

transformed_words <- beginWord

while (transformed_words is not empty) {

    for (word_b in transformed_words) {

        if (endWord is within 1 distance) {

            return distance

        }

        if (some word in dict is within 1 distance

             && it is not in transformed_words) {

            transformed_words.add(word)

        }

    }

    update distance

}

return 0

How to check?

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder

transformed_words <- beginWord

while (transformed_words is not empty) {

    for (word_b in transformed_words) {

        if (endWord is within 1 distance) {

            return distance

        }

        if (some word in dict is within 1 distance

             && it is not in transformed_words) {

            transformed_words.add(word)

        }

    }

    update distance

}

return 0

How to check?

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder

public int ladderLength(String beginWord, String endWord,
                        Set<String> wordList) {
    wordList.add(endWord);
    Queue<String> queue = new LinkedList<>();
    queue.offer(beginWord);
    Set<String> visited = new HashSet<>();
    visited.add(beginWord);
    int distance = 1;
    while (!queue.isEmpty()) {
        Queue<String> queue2 = new LinkedList<>();
        distance++;
        while (!queue.isEmpty()) {
            String top = queue.poll();
            List<String> wordsWithinDistance =
                getWordsWithinDistance(wordList, top);
            for (String word : wordsWithinDistance) {
                if (word.equals(endWord)) {
                    return distance;
                }
                if (!visited.contains(word)) {
                    queue2.add(word);
                    visited.add(word);
                }
            }
        }
        queue = queue2;
    }
    return 0;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder

public ArrayList<String> getWordsWithinDistance(
    Set<String> wordList, String word) {
    ArrayList<String> results = new ArrayList<>();
    char[] wordCharArr = word.toCharArray();
    for (int i = 0; i < word.length(); i++) {
        char oriChar = wordCharArr[i];
        for (char c = 'a'; c <= 'z'; c++) {
            if (c == oriChar) {
                continue;
            }
            wordCharArr[i] = c;
            String newStr = new String(wordCharArr);
            if (wordList.contains(newStr)) {
                results.add(newStr);
            }
        }
        wordCharArr[i] = oriChar;
    }
    return results;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder

public int ladderLength(String beginWord, String endWord,
                        Set<String> wordList) {
    wordList.add(endWord);
    wordList.remove(beginWord); // This is optional
    Queue<String> queue = new LinkedList<>();
    queue.offer(beginWord);
    int distance = 1;
    while (!queue.isEmpty() && !wordList.isEmpty()) {
        Queue<String> queue2 = new LinkedList<>();
        distance++;
        while (!queue.isEmpty()) {
            String top = queue.poll();
            ArrayList<String> wordsWithinDistance =
                getWordsWithinDistance(wordList, top);
            if (wordsWithinDistance.contains(endWord)) {
                return distance;
            }
            queue2.addAll(wordsWithinDistance);
        }
        queue = queue2;
    }
    return 0;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder

public ArrayList<String> getWordsWithinDistance(Set<String> wordList,
                                                String word) {
    ArrayList<String> results = new ArrayList<>();
    char[] wordCharArr = word.toCharArray();
    for (int i = 0; i < word.length(); i++) {
        char oriChar = wordCharArr[i];
        for (char c = 'a'; c <= 'z'; c++) {
            if (c == oriChar) {
                continue;
            }
            wordCharArr[i] = c;
            String newStr = new String(wordCharArr);
            if (wordList.contains(newStr)) {
                results.add(newStr);
                wordList.remove(newStr);
            }
        }
        wordCharArr[i] = oriChar;
    }
    return results;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord

 

Example:

beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

Return

  [
    ["hit","hot","dot","dog","cog"],
    ["hit","hot","lot","log","cog"]
  ]

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord

Example:

beginWord = "hit"

endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

hit

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord

Example:

beginWord = "hit"

endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

hit

hot

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord

Example:

beginWord = "hit"

endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

hit

hot

dot

lot

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord

Example:

beginWord = "hit"

endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

hit

hot

dot

lot

dog

log

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord

Example:

beginWord = "hit"

endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

hit

hot

dot

lot

dog

log

cog

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord

Example:

beginWord = "hit"

endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

hit

hot

dot

lot

dog

log

cog

  • Visited needs to be updated after one level.
  • wordList need to be updated after one level.

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord

Example:

beginWord = "hit"

endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

hit

hot

dot

lot

dog

log

cog

  • Path needs to be recorded backwards.
  • HashMap<String, ArrayList<String>>

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord

  • BFS to get shortest transformation
  • Record the path information during transformation so that the sequence can get regenerated later.
    • ​with visited set, all nodes on the path can guarantee the shortest distance.
  • DFS to get all the transformation sequences
    • ​backward from endWord instead of forward from startWord

Copyright © 直通硅谷

http://www.zhitongguigu.com/

public List<List<String>> findLadders(String beginWord, String endWord,
                                      Set<String> wordList) {
    List<List<String>> results = new ArrayList<>();
    HashMap<String, ArrayList<String>> preList = new HashMap<>();
    
    wordList.add(endWord);
    Queue<String> queue = new LinkedList<>();
    queue.offer(beginWord);
    Set<String> visited = new HashSet<>();
    visited.add(beginWord);

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder II

    while (!queue.isEmpty() && !wordList.isEmpty()) {
        Set<String> queue2 = new HashSet<>();
        boolean isFinished = false;
        while (!queue.isEmpty()) {
            String top = queue.poll();
            Set<String> wordsWithinDistance =
                getWordsWithinDistance(wordList, top);

            for (String word : wordsWithinDistance) {
                if (word.equals(endWord)) {
                    isFinished = true;
                }
                if (!visited.contains(word)) {
                    updatePreList(preList, word, top);
                    queue2.add(word);
                }
            }
        }
        visited.addAll(queue2);
        if (isFinished) {
            getPaths(results, preList, new ArrayList<String>(), endWord);
            break;
        }
        queue.addAll(queue2);
    }
    return results;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder II

public void updatePreList(HashMap<String, ArrayList<String>> preList, 
                          String cur, String pre) {
    if (!preList.containsKey(cur)) {
        preList.put(cur, new ArrayList<String>());
    }
    preList.get(cur).add(pre);
}

public Set<String> getWordsWithinDistance(Set<String> wordList, String word) {
    Set<String> results = new HashSet<>();
    char[] wordCharArr = word.toCharArray();
    for (int i = 0; i < word.length(); i++) {
        char oriChar = wordCharArr[i];
        for (char c = 'a'; c <= 'z'; c++) {
            if (c == oriChar) {
                continue;
            }
            wordCharArr[i] = c;
            String newStr = new String(wordCharArr);
            if (wordList.contains(newStr)) {
                results.add(newStr);
            }
        }
        wordCharArr[i] = oriChar;
    }
    return results;
}

Word Ladder II

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder II

  • How to get paths backward from endWord?
    • DFS (recursion)
      • Base Case: endWord.pre == null
      • Recursion rule: path from endWord = path from endWord.pre + endWord

Copyright © 直通硅谷

http://www.zhitongguigu.com/

public void getPaths(List<List<String>> paths, 
                     HashMap<String, ArrayList<String>> preList,
                     List<String> curPath,
                     String end) {
    if (!preList.containsKey(end)) {
        curPath.add(end);
        Collections.reverse(curPath);
        paths.add(curPath);
        return;
    }
    for (String pre : preList.get(end)) {
        List<String> newPath = new ArrayList<String>(curPath);
        newPath.add(end);
        getPaths(paths, preList, newPath, pre);
    }
}

Word Ladder II

Copyright © 直通硅谷

http://www.zhitongguigu.com/

public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) {
    List<List<String>> results = new ArrayList<>();
    HashMap<String, ArrayList<String>> preList = new HashMap<>();
    wordList.add(endWord);
    wordList.remove(beginWord);
    Queue<String> queue = new LinkedList<>();
    queue.offer(beginWord);
    
    while (!queue.isEmpty() && !wordList.isEmpty()) {
        Set<String> queue2 = new HashSet<>();
        boolean isFinished = false;
        while (!queue.isEmpty()) {
            String top = queue.poll();
            Set<String> wordsWithinDistance = getWordsWithinDistance(wordList, top);
            for (String word : wordsWithinDistance) {
                if (word.equals(endWord)) {
                    isFinished = true;
                }
                updatePreList(preList, word, top);
                queue2.add(word);
            }
        }
        wordList.removeAll(queue2);
        if (isFinished) {
            getPaths(results, preList, new ArrayList<String>(), endWord);
            break;
        }
        queue.addAll(queue2);
    }
    return results;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

public List<List<String>> findLadders(String beginWord, String endWord, Set<String> wordList) {
    List<List<String>> results = new ArrayList<>();
    HashMap<String, ArrayList<String>> preList = new HashMap<>();
    wordList.add(endWord);
    wordList.remove(beginWord);
    Queue<String> queue = new LinkedList<>();
    queue.offer(beginWord);
    
    while (!queue.isEmpty() && !wordList.isEmpty()) {
        Set<String> queue2 = new HashSet<>();
        boolean isFinished = false;
        while (!queue.isEmpty()) {
            String top = queue.poll();
            Set<String> wordsWithinDistance = getWordsWithinDistance(wordList, top);
            updatePreList(preList, wordsWithinDistance, top);
            queue2.addAll(wordsWithinDistance);
            isFinished = isFinished | wordsWithinDistance.contains(endWord);
        }
        wordList.removeAll(queue2);
        if (isFinished) {
            getPaths(results, preList, new ArrayList<String>(), endWord);
            break;
        }
        queue.addAll(queue2);
    }
    return results;
}
public void updatePreList(HashMap<String, ArrayList<String>> preList,
                          Set<String> curStrings, String pre) {
    for (String cur : curStrings) {
        if (!preList.containsKey(cur)) {
            preList.put(cur, new ArrayList<String>());
        }
        preList.get(cur).add(pre);
    }
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Word Ladder II

Given two words (beginWord and endWord), and a dictionary's word list, find all shortest transformation sequence(s) from beginWord to endWord

  • BFS to get shortest transformation
  • Record the paths from beginning while BFSing
  • Add only the valid paths into results.

Copyright © 直通硅谷

http://www.zhitongguigu.com/

  • Distance means level important
    • Two queues
      • Order is not important, so queue is not essential actually.
    • Dummy node
  • Pruning for duplicate word
    • HashSet for visited words
    • Remove from dict.
  • Spell check
    • Word, Google Docs, etc.

BFS for Word Distance

Copyright © 直通硅谷

http://www.zhitongguigu.com/

  • Shortest path
    • Dijkstra's Algorithm
  • Maze solving
    • The minimum steps needed

BFS for Distance

Copyright © 直通硅谷

http://www.zhitongguigu.com/

  • Both complete search
  • DFS is recursion
    • stack
    • better at checking connection, etc.
  • BFS is iteration
    • queue
    • better at minimum distance, etc.
  • Many problems are both solvable by DFS/BFS
    • Surrounded Region
    • Number of Islands
    • etc.

DFS v.s. BFS

Copyright © 直通硅谷

http://www.zhitongguigu.com/

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

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

Surrounded Region

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

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

Copyright © 直通硅谷

http://www.zhitongguigu.com/

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

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

Surrounded Region

public void solve(char[][] board) {
    if (board.length == 0 || board[0].length == 0)
        return;

    for (int j = 0; j < board[0].length; j++) {
        search(board, 0, j);
        search(board, board.length-1, j);
    }
    for (int i = 0; i < board.length; i++) {
        search(board, i, 0);
        search(board, i, board[0].length-1);
    }
    
    for (int i = 0; i < board.length; i++) {
        for (int j = 0; j < board[0].length; j++) {
            board[i][j] = board[i][j] == 'F' ? 'O' : 'X';
        }
    }
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

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

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

Surrounded Region

// BFS
public void search(char[][] board, int x, int y) {
    if (board[x][y] == 'X') {
        return;
    }
    Queue<Integer> queue = new LinkedList<Integer>();
    int xLen = board.length, yLen = board[0].length;
    int[] dx = {-1, 0, 1, 0};
    int[] dy = {0, 1, 0, -1};
    
    queue.offer(x * yLen + y);
    board[x][y] = 'F';

    while (!queue.isEmpty()) {
        int temp = queue.poll();
        for (int i = 0; i < 4; i++) {
            int nx = temp / yLen + dx[i], ny = temp % yLen + dy[i];
            if (nx >= 0 && nx < xLen && ny >= 0 && ny < yLen
                && board[nx][ny] == 'O') {
                board[nx][ny] = 'F';
                queue.offer(nx * yLen + ny);
	    }
	}
    }
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

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

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

Surrounded Region

// DFS
public void search(char[][] board, int i, int j) {
    if (board[i][j] != 'O')
	return;
    board[i][j] = 'F';
    if (i > 1)
	search(board, i-1, j);
    if (i < board.length - 2)
	search(board, i+1, j);
    if (j > 1)
	search(board, i, j-1);
    if (j < board[i].length - 2)
	search(board, i, j+1);
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

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

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

Surrounded Region

// DFS
public void search(char[][] board, int i, int j) {
    if (board[i][j] != 'O')
	return;
    board[i][j] = 'F';
    if (i >= 1)
	search(board, i-1, j);
    if (i <= board.length - 2)
	search(board, i+1, j);
    if (j >= 1)
	search(board, i, j-1);
    if (j <= board[i].length - 2)
	search(board, i, j+1);
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Stack Overflow

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.

Number of Islands

11110
11010
11000
00000 

11000
11000
00100
00011

1

3

Copyright © 直通硅谷

http://www.zhitongguigu.com/

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.

Number of Islands

public int numIslands(char[][] grid) {
    if (grid == null || grid.length == 0 || grid[0].length == 0) {
        return 0;
    }
    int nums = 0;
    for (int i = 0; i < grid.length; i++) {
        for (int j = 0; j < grid[0].length; j++) {
            if (grid[i][j] == '1') {
                search(grid, i, j);
                nums++;
            }
        }
    }
    return nums;
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

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.

Number of Islands

// DFS
public void search(char[][] grid, int x, int y) {
    if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length) {
        return;
    }
    if (grid[x][y] == '1') {
        grid[x][y] = '0';
        search(grid, x + 1, y);
        search(grid, x - 1, y);
        search(grid, x, y + 1);
        search(grid, x, y - 1);
    }
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

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.

Number of Islands

// BFS
public void search(char[][] grid, int x, int y) {
    Queue<Integer> queue = new LinkedList<>();
    int xLen = grid.length, yLen = grid[0].length;
    queue.offer(x * yLen + y);
    grid[x][y] = '0';
    
    int[] dx = {-1, 0, 1, 0};
    int[] dy = {0, 1, 0, -1};
    while (!queue.isEmpty()) {
        Integer top = queue.poll();
        
        for (int i = 0; i < 4; i++) {
            int nx = top/yLen + dx[i], ny = top%yLen + dy[i];
            if (nx >= 0 && nx < xLen && ny >= 0 && ny < yLen
                && grid[nx][ny] == '1') {
                grid[nx][ny] = '0';
                queue.offer(nx * yLen + ny);
            }
        }
    }
}

Copyright © 直通硅谷

http://www.zhitongguigu.com/

Homework

Copyright © 直通硅谷

http://www.zhitongguigu.com/

[GoValley-201612] BFS

By govalley201612

[GoValley-201612] BFS

  • 819