Implement Trie II — Advanced Operations

Implement trieAdvancedQuery

A trie can track more than just "does this word exist" — it can count. Given a list of words to insert (duplicates allowed — the same word can be inserted more than once) followed by a list of erasures to remove one occurrence each of, answer one of two questions about a single query: exactly how many currently-present words equal it, or how many currently-present words have it as a prefix? The trick is giving every trie node two running totals instead of one flag: how many inserted words end exactly at that node, and how many pass through it at all (ending there or continuing further). Inserting a word increments the "passes through" total all along its path and the "ends here" total at the final node; erasing does the same in reverse, but only when a copy genuinely exists to remove — so an erasure can never push either total below zero. Once built, a query is just one walk down to the relevant node, reading off whichever total the question asked about.

Example 1:

Input: words = ["apple","apple","apple"], erasures = [], query = "apple", isPrefixQuery = false

Output: 3

Example 2:

Input: words = ["apple","apple","apple"], erasures = ["apple"], query = "apple", isPrefixQuery = false

Output: 2

Example 3:

Input: words = ["apple","app","application"], erasures = [], query = "app", isPrefixQuery = true

Output: 3

+ 9 hidden test cases run on Submit.

Constraints:

  • 0 ≤ words.length, erasures.length ≤ 1000
  • 1 ≤ words[i].length, erasures[i].length ≤ 30
  • 0 ≤ query.length ≤ 30
  • words[i], erasures[i], and query consist of lowercase English letters
  • an erasure applied when nothing matching remains to erase is simply a no-op

words =

["apple", "apple", "apple"]

erasures =

[]

query =

apple

isPrefixQuery =

false