From a95caa60c895f9ba5ac328121c80d0495359c1d4 Mon Sep 17 00:00:00 2001 From: Edoardo Baldi Date: Thu, 19 Dec 2024 20:31:57 +0100 Subject: [PATCH] Day 19: add explanation How the "search" method of the "Trie" class works --- 19/python/explanation.md | 86 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 19/python/explanation.md diff --git a/19/python/explanation.md b/19/python/explanation.md new file mode 100644 index 0000000..433af42 --- /dev/null +++ b/19/python/explanation.md @@ -0,0 +1,86 @@ +## Explanation of the `search` method of the `Trie` class + +Here's the `search` method of the `Trie` class: + +```python +def search(self, string: str, debug: bool = False) -> bool: + n = len(string) + dp = [True] + [False] * n + + for i in range(n): + if debug: + print(dp) + + if not dp[i]: + continue + + node = self.root + j = i + while j < n and string[j] in node.children: + node = node.children[string[j]] + j += 1 + if node.is_end: + dp[j] = True + if j == n: + return True + return dp[n] +``` + +Say that we have the following trie – where `*` denotes a a node that marks the end of a pattern: + +``` +b* + r* + w + u* +g* + b* +r* + b* +w + r* +``` + +Here's the output when we try to search for the string `brwrr`: + +``` +Searching for string: brwrr +Initial dp: [True, False, False, False, False, False] + +Trying from position 0 (brwrr) + Looking for patterns: + Found pattern b -> marking dp[1] = True + Found pattern br -> marking dp[2] = True + dp after position 0: [True, True, True, False, False, False] + +Trying from position 1 (rwrr) + Looking for patterns: + Found pattern r -> marking dp[2] = True + dp after position 1: [True, True, True, False, False, False] + +Trying from position 2 (wrr) + Looking for patterns: + Found pattern wr -> marking dp[4] = True + dp after position 2: [True, True, True, False, True, False] + +Trying from position 3 (rr) + Skipping pos 3 since dp[3] is False + +Trying from position 4 (r) + Looking for patterns: + Found pattern r -> marking dp[5] = True + dp after position 4: [True, True, True, False, True, True] + +Final dp: [True, True, True, False, True, True] +``` + +It's crucial to understand what the list `dp` represents: `dp[i] = True` means that we can build the substring `string[0:i]` (where `i` is **not** included, as per Python indexing/slicing rules) using available patterns. + +For example, considering the string `brwrr`: + +- `dp[0] = True`: can build empty string, which is always possible +- `dp[1] = True`: can build "b" (since we have a pattern "b") +- `dp[2] = True`: can build "br" (since we have a pattern "br") +- `dp[3] = False`: cannot build "brw" because "w" only appears in pattern "wr", never alone +- `dp[4] = True`: can build "brwr" (since we have a pattern "br" + "wr") +- `dp[5] = True`: can build "brwrr" (since we have a pattern "br" + "wr" + "r")