-
-
Notifications
You must be signed in to change notification settings - Fork 46.9k
add word_break dynamic approach up -> down. #8039
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 8 commits
da0bb4c
319aca4
4986ea3
ba0f0d6
00519c0
53ab4d5
df0a910
1e6a4a8
37cb004
dcbe9c3
7bef651
51baf03
ab64273
3f7292a
9368d25
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
""" | ||
Author : Alexander Pantyukhin | ||
Date : December 12, 2022 | ||
|
||
Task: | ||
Given a string s and a dictionary of strings wordDict, | ||
return true if s can be segmented into a space-separated | ||
sequence of one or more dictionary words. | ||
|
||
Note that the same word in the dictionary may be reused | ||
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
multiple times in the segmentation. | ||
|
||
Implementation notes: Trie + Dynamic programming up -> down. | ||
The Trie keeps all wordDict words. It will be useful for scanning | ||
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
available words for the current position in the string. | ||
|
||
Leetcode: | ||
https://leetcode.com/problems/word-break/description/ | ||
|
||
Runtime: O(n * n) | ||
Space: O(n) | ||
""" | ||
|
||
from functools import lru_cache | ||
|
||
|
||
def word_break(string: str, word_dict: list[str]) -> bool: | ||
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
Return True if numbers have opposite signs False otherwise. | ||
|
||
>>> word_break("applepenapple", ["apple","pen"]) | ||
True | ||
>>> word_break("catsandog", ["cats","dog","sand","and","cat"]) | ||
False | ||
>>> word_break("cars", ["car","ca","rs"]) | ||
True | ||
>>> word_break('abc', []) | ||
False | ||
>>> word_break(123, ['a']) | ||
Traceback (most recent call last): | ||
... | ||
ValueError: the string should be not empty string | ||
>>> word_break('', ['a']) | ||
Traceback (most recent call last): | ||
... | ||
ValueError: the string should be not empty string | ||
>>> word_break('abc', [123]) | ||
Traceback (most recent call last): | ||
... | ||
ValueError: the word_dict should a list of non empty string | ||
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
>>> word_break('abc', ['']) | ||
Traceback (most recent call last): | ||
... | ||
ValueError: the word_dict should a list of non empty string | ||
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
""" | ||
|
||
# Validation | ||
if not isinstance(string, str) or len(string) == 0: | ||
raise ValueError("the string should be not empty string") | ||
|
||
if not isinstance(word_dict, list) or not all( | ||
[isinstance(item, str) and len(item) > 0 for item in word_dict] | ||
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
): | ||
raise ValueError("the word_dict should a list of non empty string") | ||
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
# Build trie | ||
trie: Dict[str, Any] = {} | ||
word_keeper_key = "WORD_KEEPER" | ||
for word in word_dict: | ||
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
trie_node = trie | ||
for c in word: | ||
if c not in trie_node: | ||
trie_node[c] = {} | ||
|
||
trie_node = trie_node[c] | ||
|
||
trie_node[word_keeper_key] = True | ||
|
||
len_string = len(string) | ||
|
||
# Dynamic programming method | ||
@lru_cache(maxsize=None) | ||
def is_breakable(index: int) -> bool: | ||
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
alexpantyukhin marked this conversation as resolved.
Show resolved
Hide resolved
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there is no test file in this pull request nor any test function or class in the file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there is no test file in this pull request nor any test function or class in the file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there is no test file in this pull request nor any test function or class in the file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there is no test file in this pull request nor any test function or class in the file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there is no test file in this pull request nor any test function or class in the file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there is no test file in this pull request nor any test function or class in the file There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As there is no test file in this pull request nor any test function or class in the file |
||
if index == len_string: | ||
return True | ||
|
||
trie_node = trie | ||
for i in range(index, len_string): | ||
trie_node = trie_node.get(string[i], None) | ||
|
||
if trie_node is None: | ||
return False | ||
|
||
if trie_node.get(word_keeper_key, False) and is_breakable(i + 1): | ||
return True | ||
|
||
return False | ||
|
||
return is_breakable(0) | ||
|
||
|
||
if __name__ == "__main__": | ||
import doctest | ||
|
||
doctest.testmod() |
Uh oh!
There was an error while loading. Please reload this page.