Skip to content

Commit 3ed7cc6

Browse files
committed
adds tries
1 parent 6fed9e7 commit 3ed7cc6

File tree

1 file changed

+163
-0
lines changed

1 file changed

+163
-0
lines changed
Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"metadata": {},
6+
"source": [
7+
"# Data Structure - Tries"
8+
]
9+
},
10+
{
11+
"cell_type": "markdown",
12+
"metadata": {},
13+
"source": [
14+
"## [211. Design Add and Search Words Data Structure](https://leetcode.com/problems/design-add-and-search-words-data-structure/)"
15+
]
16+
},
17+
{
18+
"cell_type": "code",
19+
"execution_count": 12,
20+
"metadata": {},
21+
"outputs": [],
22+
"source": [
23+
"class TrieNode:\n",
24+
" def __init__(self):\n",
25+
" self.children = {}\n",
26+
" self.is_leaf = False\n",
27+
"\n",
28+
"class WordDictionary:\n",
29+
" def __init__(self):\n",
30+
" \"\"\"\n",
31+
" Initialize your data structure here.\n",
32+
" \"\"\"\n",
33+
" self.root = TrieNode()\n",
34+
"\n",
35+
" def addWord(self, word: str) -> None:\n",
36+
" node = self.root\n",
37+
" for letter in word:\n",
38+
" if letter in node.children:\n",
39+
" node = node.children[letter]\n",
40+
" else:\n",
41+
" new_node = TrieNode()\n",
42+
" node.children[letter] = new_node\n",
43+
" node = new_node\n",
44+
" node.is_leaf = True\n",
45+
"\n",
46+
" def _search(self, word, i, node):\n",
47+
" if i == len(word):\n",
48+
" return node.is_leaf\n",
49+
" if word[i] == \".\":\n",
50+
" for child in node.children.values():\n",
51+
" if self._search(word, i+1, child):\n",
52+
" return True\n",
53+
" return False\n",
54+
" if word[i] not in node.children:\n",
55+
" return False\n",
56+
" return self._search(word, i+1, node.children[word[i]])\n",
57+
"\n",
58+
" def search(self, word: str) -> bool:\n",
59+
" return self._search(word, 0, self.root)\n",
60+
"\n",
61+
"null, true, false = None, True, False\n",
62+
"cases = [\n",
63+
" [\n",
64+
" [\"addWord\",\"addWord\",\"search\",\"search\",\"search\",\"search\",\"search\",\"search\",\"search\",\"search\"],\n",
65+
" [[\"a\"],[\"ab\"],[\"a\"],[\"a.\"],[\"ab\"],[\".a\"],[\".b\"],[\"ab.\"],[\".\"],[\"..\"]],\n",
66+
" [null,null,true,true,true,false,true,false,true,true]\n",
67+
" ]\n",
68+
"]\n",
69+
"wd = WordDictionary()\n",
70+
"for commands, args, expecteds in cases:\n",
71+
" for i, _ in enumerate(commands):\n",
72+
" command = commands[i]\n",
73+
" arg = args[i][0]\n",
74+
" expected = expecteds[i]\n",
75+
" if command == \"addWord\":\n",
76+
" wd.addWord(arg)\n",
77+
" else:\n",
78+
" actual = wd.search(arg)\n",
79+
" assert expected == actual, f\"{command,arg}: {expected} != {actual}\"\n",
80+
" \n"
81+
]
82+
},
83+
{
84+
"cell_type": "markdown",
85+
"metadata": {},
86+
"source": [
87+
"## [421. Maximum XOR of Two Numbers in an Array](https://leetcode.com/problems/maximum-xor-of-two-numbers-in-an-array/)\n",
88+
"\n",
89+
"This one uses a bitwise trie, which is really a kind of binary tree.\n",
90+
" "
91+
]
92+
},
93+
{
94+
"cell_type": "code",
95+
"execution_count": 109,
96+
"metadata": {},
97+
"outputs": [],
98+
"source": [
99+
"from typing import List\n",
100+
"\n",
101+
"def flipped(bit):\n",
102+
" return '0' if bit == '1' else '1'\n",
103+
"\n",
104+
"class Solution:\n",
105+
" def findMaximumXOR(self, nums: List[int]) -> int:\n",
106+
" root = {}\n",
107+
" required = len(bin(max(nums))[2:])\n",
108+
" bitstrs = [bin(val)[2:].zfill(required) for val in nums]\n",
109+
" for bitstr in bitstrs:\n",
110+
" node = root\n",
111+
" for bit in bitstr:\n",
112+
" if bit not in node:\n",
113+
" node[bit] = {}\n",
114+
" node = node[bit]\n",
115+
" \n",
116+
" best_xor = 0\n",
117+
" for bitstr in bitstrs:\n",
118+
" curr_xor = ''\n",
119+
" node = root\n",
120+
" for bit in bitstr:\n",
121+
" next_bit = flipped(bit) if flipped(bit) in node else bit\n",
122+
" curr_xor += '1' if next_bit != bit else '0'\n",
123+
" node = node[next_bit]\n",
124+
" best_xor = max(best_xor, int(curr_xor,2))\n",
125+
" return best_xor\n",
126+
" \n",
127+
"s = Solution()\n",
128+
"cases = [\n",
129+
" ([3,10,5,25,2,8], 28),\n",
130+
" ([0], 0),\n",
131+
" ([2,4], 6),\n",
132+
" ([8,10,2], 10),\n",
133+
" ([14,70,53,83,49,91,36,80,92,51,66,70], 127),\n",
134+
" ([32,18,33,42,29,20,26,36,15,46], 62)\n",
135+
"]\n",
136+
"for vals, expected in cases:\n",
137+
" actual = s.findMaximumXOR(vals)\n",
138+
" assert actual == expected, f\"{vals}: {expected} != {actual}\""
139+
]
140+
}
141+
],
142+
"metadata": {
143+
"kernelspec": {
144+
"display_name": "Python 3",
145+
"language": "python",
146+
"name": "python3"
147+
},
148+
"language_info": {
149+
"codemirror_mode": {
150+
"name": "ipython",
151+
"version": 3
152+
},
153+
"file_extension": ".py",
154+
"mimetype": "text/x-python",
155+
"name": "python",
156+
"nbconvert_exporter": "python",
157+
"pygments_lexer": "ipython3",
158+
"version": "3.8.5"
159+
}
160+
},
161+
"nbformat": 4,
162+
"nbformat_minor": 4
163+
}

0 commit comments

Comments
 (0)