返回介绍

solution / 0700-0799 / 0745.Prefix and Suffix Search / README_EN

发布于 2024-06-17 01:03:34 字数 9192 浏览 0 评论 0 收藏 0

745. Prefix and Suffix Search

中文文档

Description

Design a special dictionary that searches the words in it by a prefix and a suffix.

Implement the WordFilter class:

  • WordFilter(string[] words) Initializes the object with the words in the dictionary.
  • f(string pref, string suff) Returns _the index of the word in the dictionary,_ which has the prefix pref and the suffix suff. If there is more than one valid index, return the largest of them. If there is no such word in the dictionary, return -1.

 

Example 1:

Input
["WordFilter", "f"]
[[["apple"]], ["a", "e"]]
Output
[null, 0]
Explanation
WordFilter wordFilter = new WordFilter(["apple"]);
wordFilter.f("a", "e"); // return 0, because the word at index 0 has prefix = "a" and suffix = "e".

 

Constraints:

  • 1 <= words.length <= 104
  • 1 <= words[i].length <= 7
  • 1 <= pref.length, suff.length <= 7
  • words[i], pref and suff consist of lowercase English letters only.
  • At most 104 calls will be made to the function f.

Solutions

Solution 1

class WordFilter:
  def __init__(self, words: List[str]):
    self.d = {}
    for k, w in enumerate(words):
      n = len(w)
      for i in range(n + 1):
        a = w[:i]
        for j in range(n + 1):
          b = w[j:]
          self.d[(a, b)] = k

  def f(self, pref: str, suff: str) -> int:
    return self.d.get((pref, suff), -1)


# Your WordFilter object will be instantiated and called as such:
# obj = WordFilter(words)
# param_1 = obj.f(pref,suff)
class WordFilter {
  private Map<String, Integer> d = new HashMap<>();

  public WordFilter(String[] words) {
    for (int k = 0; k < words.length; ++k) {
      String w = words[k];
      int n = w.length();
      for (int i = 0; i <= n; ++i) {
        String a = w.substring(0, i);
        for (int j = 0; j <= n; ++j) {
          String b = w.substring(j);
          d.put(a + "." + b, k);
        }
      }
    }
  }

  public int f(String pref, String suff) {
    return d.getOrDefault(pref + "." + suff, -1);
  }
}

/**
 * Your WordFilter object will be instantiated and called as such:
 * WordFilter obj = new WordFilter(words);
 * int param_1 = obj.f(pref,suff);
 */
class WordFilter {
public:
  unordered_map<string, int> d;

  WordFilter(vector<string>& words) {
    for (int k = 0; k < words.size(); ++k) {
      string w = words[k];
      int n = w.size();
      for (int i = 0; i <= n; ++i) {
        string a = w.substr(0, i);
        for (int j = 0; j <= n; ++j) {
          string b = w.substr(j, n - j);
          d[a + "." + b] = k;
        }
      }
    }
  }

  int f(string pref, string suff) {
    string key = pref + "." + suff;
    if (d.count(key)) return d[key];
    return -1;
  }
};

/**
 * Your WordFilter object will be instantiated and called as such:
 * WordFilter* obj = new WordFilter(words);
 * int param_1 = obj->f(pref,suff);
 */
type WordFilter struct {
  d map[string]int
}

func Constructor(words []string) WordFilter {
  d := map[string]int{}
  for k, w := range words {
    n := len(w)
    for i := 0; i <= n; i++ {
      a := w[:i]
      for j := 0; j <= n; j++ {
        b := w[j:]
        d[a+"."+b] = k
      }
    }
  }
  return WordFilter{d}
}

func (this *WordFilter) F(pref string, suff string) int {
  if v, ok := this.d[pref+"."+suff]; ok {
    return v
  }
  return -1
}

/**
 * Your WordFilter object will be instantiated and called as such:
 * obj := Constructor(words);
 * param_1 := obj.F(pref,suff);
 */

Solution 2

class Trie:
  def __init__(self):
    self.children = [None] * 26
    self.indexes = []

  def insert(self, word, i):
    node = self
    for c in word:
      idx = ord(c) - ord("a")
      if node.children[idx] is None:
        node.children[idx] = Trie()
      node = node.children[idx]
      node.indexes.append(i)

  def search(self, pref):
    node = self
    for c in pref:
      idx = ord(c) - ord("a")
      if node.children[idx] is None:
        return []
      node = node.children[idx]
    return node.indexes


class WordFilter:
  def __init__(self, words: List[str]):
    self.p = Trie()
    self.s = Trie()
    for i, w in enumerate(words):
      self.p.insert(w, i)
      self.s.insert(w[::-1], i)

  def f(self, pref: str, suff: str) -> int:
    a = self.p.search(pref)
    b = self.s.search(suff[::-1])
    if not a or not b:
      return -1
    i, j = len(a) - 1, len(b) - 1
    while ~i and ~j:
      if a[i] == b[j]:
        return a[i]
      if a[i] > b[j]:
        i -= 1
      else:
        j -= 1
    return -1


# Your WordFilter object will be instantiated and called as such:
# obj = WordFilter(words)
# param_1 = obj.f(pref,suff)
class Trie {
  Trie[] children = new Trie[26];
  List<Integer> indexes = new ArrayList<>();

  void insert(String word, int i) {
    Trie node = this;
    for (char c : word.toCharArray()) {
      c -= 'a';
      if (node.children[c] == null) {
        node.children[c] = new Trie();
      }
      node = node.children[c];
      node.indexes.add(i);
    }
  }

  List<Integer> search(String pref) {
    Trie node = this;
    for (char c : pref.toCharArray()) {
      c -= 'a';
      if (node.children[c] == null) {
        return Collections.emptyList();
      }
      node = node.children[c];
    }
    return node.indexes;
  }
}

class WordFilter {
  private Trie p = new Trie();
  private Trie s = new Trie();

  public WordFilter(String[] words) {
    for (int i = 0; i < words.length; ++i) {
      String w = words[i];
      p.insert(w, i);
      s.insert(new StringBuilder(w).reverse().toString(), i);
    }
  }

  public int f(String pref, String suff) {
    suff = new StringBuilder(suff).reverse().toString();
    List<Integer> a = p.search(pref);
    List<Integer> b = s.search(suff);
    if (a.isEmpty() || b.isEmpty()) {
      return -1;
    }
    int i = a.size() - 1, j = b.size() - 1;
    while (i >= 0 && j >= 0) {
      int c = a.get(i), d = b.get(j);
      if (c == d) {
        return c;
      }
      if (c > d) {
        --i;
      } else {
        --j;
      }
    }
    return -1;
  }
}

/**
 * Your WordFilter object will be instantiated and called as such:
 * WordFilter obj = new WordFilter(words);
 * int param_1 = obj.f(pref,suff);
 */
type Trie struct {
  children [26]*Trie
  indexes  []int
}

func newTrie() *Trie {
  return &Trie{indexes: []int{}}
}
func (this *Trie) insert(word string, i int) {
  node := this
  for _, c := range word {
    idx := c - 'a'
    if node.children[idx] == nil {
      node.children[idx] = newTrie()
    }
    node = node.children[idx]
    node.indexes = append(node.indexes, i)
  }
}

func (this *Trie) search(pref string) []int {
  node := this
  for _, c := range pref {
    idx := c - 'a'
    if node.children[idx] == nil {
      return []int{}
    }
    node = node.children[idx]
  }
  return node.indexes
}

type WordFilter struct {
  p *Trie
  s *Trie
}

func Constructor(words []string) WordFilter {
  p := newTrie()
  s := newTrie()
  for i, w := range words {
    p.insert(w, i)
    s.insert(reverse(w), i)
  }
  return WordFilter{p, s}
}

func (this *WordFilter) F(pref string, suff string) int {
  a := this.p.search(pref)
  b := this.s.search(reverse(suff))
  if len(a) == 0 || len(b) == 0 {
    return -1
  }
  i, j := len(a)-1, len(b)-1
  for i >= 0 && j >= 0 {
    if a[i] == b[j] {
      return a[i]
    }
    if a[i] > b[j] {
      i--
    } else {
      j--
    }
  }
  return -1
}

func reverse(w string) string {
  ww := []byte(w)
  for i, j := 0, len(w)-1; i < j; i++ {
    ww[i], ww[j] = ww[j], ww[i]
    j--
  }
  return string(ww)
}

/**
 * Your WordFilter object will be instantiated and called as such:
 * obj := Constructor(words);
 * param_1 := obj.F(pref,suff);
 */

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文