算法:回溯十六 Add and Search Word添加并查找单词

核能气质少年 提交于 2020-01-20 13:34:52

题目

地址: https://leetcode.com/problems/add-and-search-word-data-structure-design/

Add and Search Word - Data structure design
Design a data structure that supports the following two operations:

void addWord(word)
bool search(word)

search(word) can search a literal word or a regular expression string containing only letters a-z or … A . means it can represent any one letter.

Example:

addWord("bad")
addWord("dad")
addWord("mad")
search("pad") -> false
search("bad") -> true
search(".ad") -> true
search("b..") -> true

Note:
You may assume that all words are consist of lowercase letters a-z.

DFS回溯解法

思路解析:
这里用到字典树的结构,参考维基百科Tire
Map<Character, TrieNode> childMap来连接上下的字母,如果是完整单词则标识boolean isWord
在这里插入图片描述

  1. 增加单词解析
    从根节点root开始解析,如果childMap没有包含该key,则添加。把子节点指向当前节点。

  2. 查找单词解析
    1)如果查找到单词word末尾,则判断字典树当前节点是否为结束节点,如果是,则返回true;否则返回false。
    2)如果单词word为结束,而当前节点childMap以及是空,则返回false。
    3)如果word的当前字符是., 则遍历所有的子节点。
    4)如果word的当前字符, 在字典树中没找到,则返回false。
    5)如果word的当前字符,在字典树中找到,则找下个子节点。

package backtracking;

// https://leetcode.com/problems/add-and-search-word-data-structure-design/

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * Your WordDictionary object will be instantiated and called as such:
 * WordDictionary obj = new WordDictionary();
 * obj.addWord(word);
 * boolean param_2 = obj.search(word);
 */
public class WordDictionary {

  private class TrieNode {
    private boolean isWord;
    private Map<Character, TrieNode> childMap;

    public TrieNode() {
      isWord = false;
      childMap = new HashMap<Character, TrieNode>();
    }

  }

  private TrieNode root;

  /** Initialize your data structure here. */
  public WordDictionary() {
    root = new TrieNode();
  }

  /** Adds a word into the data structure. */
  public void addWord(String word) {
    TrieNode curr = root;
    for (char c: word.toCharArray()) {
      if (!curr.childMap.containsKey(c)) {
        curr.childMap.put(c, new TrieNode());
      }
      curr = curr.childMap.get(c);
    }

    curr.isWord = true;
  }

  /** Returns if the word is in the data structure. A word could contain the dot character '.' to represent any one letter. */
  public boolean search(String word) {
    return dfs(word,0, root);
  }

  public boolean dfs(String word, int pos, TrieNode node) {
    // if the word has all been scanned, return
    if (pos == word.length()) {
      return node.isWord;
    }
    // reach the leaf before finishing scanning the word
    if (node.childMap.size() == 0) {
      return false;
    }

    Character c = word.charAt(pos);
    // if the character at current position is '.',
    // recursive check whether the remaining word is in the trie
    if (c == '.') {
      for (char item: node.childMap.keySet()) {
        if (dfs(word, pos + 1, node.childMap.get(item))) {
          return true;
        }
      }
    }

    // if character at position 'pos' is neither equal to the node nor '.', return false
    if (!node.childMap.containsKey(c)) {
      return false;
    }

    // if character at current position matches the node,
    // recursively search the remaining word
    return dfs(word, pos + 1, node.childMap.get(c));
  }

  public static void main(String[] args) {
    WordDictionary obj = new WordDictionary();
    obj.addWord("bad");
    obj.addWord("dad");
    obj.addWord("mad");
    obj.addWord("a");
    System.out.println(obj.search("pad"));
    System.out.println(obj.search("bad"));
    System.out.println(obj.search(".ad"));
    System.out.println(obj.search("b.."));
    //obj.search("pad") -> false
    //obj.search("bad") -> true
    //obj.search(".ad") -> true
    //obj.search("b..") -> true
  }
}

代码下载

https://github.com/zgpeace/awesome-java-leetcode/blob/master/code/LeetCode/src/backtracking/WordDictionary.java

参考

https://zh.wikipedia.org/wiki/Trie

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!