30 not hard but think hard
This commit is contained in:
parent
9ca72f3125
commit
331fc02f5f
146
30-240604/main.py
Normal file
146
30-240604/main.py
Normal file
@ -0,0 +1,146 @@
|
||||
class TrieNode:
|
||||
def __init__(self, val = ''):
|
||||
self.child = []
|
||||
self.is_word = 0
|
||||
self.val = val
|
||||
self.t = 1
|
||||
self.child_map = {}
|
||||
class Trie:
|
||||
def __init__(self):
|
||||
self.root = TrieNode()
|
||||
self.cnt = 0
|
||||
|
||||
def insert(self, word: str) -> None:
|
||||
parent_node = self.root
|
||||
for idx, letter in enumerate(word):
|
||||
if letter not in parent_node.child_map:
|
||||
new_node = TrieNode(letter)
|
||||
parent_node.child.append(new_node)
|
||||
parent_node.child_map[letter] = len(parent_node.child) - 1
|
||||
parent_node = new_node
|
||||
else:
|
||||
idx = parent_node.child_map[letter]
|
||||
parent_node = parent_node.child[idx]
|
||||
if parent_node.is_word != 0:
|
||||
parent_node.t += 1
|
||||
parent_node.is_word = self.cnt + 1
|
||||
self.cnt += 1
|
||||
|
||||
def search(self, word: str) :
|
||||
parent_node = self.root
|
||||
for idx, letter in enumerate(word):
|
||||
if letter not in parent_node.child_map:
|
||||
return None
|
||||
idx = parent_node.child_map[letter]
|
||||
parent_node = parent_node.child[idx]
|
||||
if parent_node.is_word != 0:
|
||||
return parent_node
|
||||
return None
|
||||
|
||||
def startsWith(self, prefix: str) -> bool:
|
||||
parent_node = self.root
|
||||
for idx, letter in enumerate(prefix):
|
||||
if letter not in parent_node.child_map:
|
||||
return False
|
||||
idx = parent_node.child_map[letter]
|
||||
parent_node = parent_node.child[idx]
|
||||
return True
|
||||
|
||||
class Solution:
|
||||
def findSubstring(self, s: str, words: list[str]) -> list[int]:
|
||||
len_word = len(words[0])
|
||||
tree = Trie()
|
||||
is_word = []
|
||||
|
||||
rlt = []
|
||||
state = []
|
||||
word_cnt = {}
|
||||
|
||||
if len_word > len(s): return []
|
||||
|
||||
for word in words:
|
||||
tree.insert(word)
|
||||
r = tree.search(word)
|
||||
if r != None:
|
||||
word_cnt[r.is_word] = r.t
|
||||
# print(word_cnt)
|
||||
|
||||
for idx, ch in enumerate(s):
|
||||
if idx + len_word > len(s): break
|
||||
waiting = s[idx:idx+len_word]
|
||||
r = tree.search(waiting)
|
||||
if r != None:
|
||||
is_word.append(r.is_word)
|
||||
else:
|
||||
is_word.append(0)
|
||||
for i in range(len_word - 1) : is_word.append(0)
|
||||
for i in range(len_word):
|
||||
if is_word[i] != 0:
|
||||
tmp_dic = {is_word[i]: [i]}
|
||||
state.append((tmp_dic,i,i))
|
||||
else:
|
||||
state.append(({},i,i))
|
||||
|
||||
if len(words) == 1 and words[0] == s:
|
||||
return [0]
|
||||
# is_word[idx] = value words index / 0 if it is not a word
|
||||
# state[dic_idx][0]
|
||||
for i in range(len(is_word[len_word:])):
|
||||
idx = i + len_word
|
||||
dic_idx = idx % len_word
|
||||
# print(f"current index: {idx}, {idx % len_word}")
|
||||
# print(f"current dic: {state[dic_idx]}")
|
||||
# print(f"is_word[idx]: {is_word[idx]}")
|
||||
if is_word[idx] in state[dic_idx][0] and len(state[dic_idx][0][is_word[idx]]) >= word_cnt[is_word[idx]]:
|
||||
# print("condition 1")
|
||||
tmp = state[dic_idx][0][is_word[idx]][0]
|
||||
tmp_l = []
|
||||
for key in state[dic_idx][0]:
|
||||
for i, v in enumerate(state[dic_idx][0][key]):
|
||||
if v <= tmp:
|
||||
tmp_l.append((key, i))
|
||||
|
||||
for (key, i) in tmp_l:
|
||||
state[dic_idx][0][key].pop(i)
|
||||
if len(state[dic_idx][0][key]) == 0:
|
||||
del state[dic_idx][0][key]
|
||||
|
||||
if is_word[idx] not in state[dic_idx][0]:
|
||||
state[dic_idx][0][is_word[idx]] = [idx]
|
||||
else:
|
||||
state[dic_idx][0][is_word[idx]].append(idx)
|
||||
state[dic_idx] = (state[dic_idx][0], tmp + len_word, state[dic_idx][2])
|
||||
elif is_word[idx] != 0:
|
||||
# print("condition 2")
|
||||
if len(state[dic_idx][0]) == 0:
|
||||
state[dic_idx] = ({}, idx, idx)
|
||||
if is_word[idx] in state[dic_idx][0]:
|
||||
state[dic_idx][0][is_word[idx]].append(idx)
|
||||
else:
|
||||
state[dic_idx][0][is_word[idx]]=[idx]
|
||||
elif is_word[idx] == 0:
|
||||
# print("condition 3")
|
||||
state[dic_idx] = ({}, idx, idx)
|
||||
|
||||
state[dic_idx] = (state[dic_idx][0],state[dic_idx][1], idx)
|
||||
s = 0
|
||||
for k in state[dic_idx][0]:
|
||||
s += len(state[dic_idx][0][k])
|
||||
# if len(state[dic_idx][0]) == len(words):
|
||||
if s == len(words):
|
||||
# print(f"win, {idx}")
|
||||
rlt.append(state[dic_idx][1])
|
||||
del state[dic_idx][0][is_word[state[dic_idx][1]]]
|
||||
state[dic_idx] = (state[dic_idx][0], state[dic_idx][1] + len_word, state[dic_idx][2])
|
||||
# print(f"after fixed: {state[dic_idx]}")
|
||||
# print()
|
||||
return rlt
|
||||
|
||||
sol = Solution()
|
||||
print(sol.findSubstring("barfoothefoobarman", words=["foo", "bar"]))
|
||||
print(sol.findSubstring("barfoofoobarthefoobarman", words=["foo", "bar", "the"]))
|
||||
print(sol.findSubstring("barbarbbar", words=["arb", "bar"]))
|
||||
print(sol.findSubstring("wordgoodgoodgoodbestword", words=["word", "good", "good", "best"]))
|
||||
print(sol.findSubstring("aaa", words=["a"]))
|
||||
print(sol.findSubstring("word", words=["word"]))
|
||||
|
Loading…
Reference in New Issue
Block a user