Skip to main content
added 2 characters in body; edited tags; edited title
Source Link
200_success
  • 145.6k
  • 22
  • 191
  • 481

Time limit exceeded solving Leet Code 139 (Word Break) using a Trietrie with recursion

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 multiple times in the segmentation.

Example 1:

Input: s = "leetcode", wordDict = ["leet","code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".

Input: s = "leetcode", wordDict = ["leet","code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".

Example 2:

Input: s = "applepenapple", wordDict = ["apple","pen"]
Output: true
Explanation: Return true because "applepenapple" can be segmented as "apple pen apple".
Note that you are allowed to reuse a dictionary word.

Input: s = "applepenapple", wordDict = ["apple","pen"]
Output: true
Explanation: Return true because "applepenapple" can be segmented as "apple pen apple". Note that you are allowed to reuse a dictionary word.

Example 3:

Input: s = "catsandog", wordDict = ["cats","dog","sand","and","cat"]
Output: false  

Input: s = "catsandog", wordDict = ["cats","dog","sand","and","cat"]
Output: false

Constraints:

  • 1 <= s.length <= 300
  • 1 <= wordDict.length <= 1000
  • 1 <= wordDict[i].length <= 20
  • s and wordDict[i] consist of only lowercase English letters.
  • All the strings of wordDict are unique.

Time limit exceeded solving Leet Code 139 using a Trie with recursion

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 multiple times in the segmentation.

Example 1:

Input: s = "leetcode", wordDict = ["leet","code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".

Example 2:

Input: s = "applepenapple", wordDict = ["apple","pen"]
Output: true
Explanation: Return true because "applepenapple" can be segmented as "apple pen apple".
Note that you are allowed to reuse a dictionary word.

Example 3:

Input: s = "catsandog", wordDict = ["cats","dog","sand","and","cat"]
Output: false  

Constraints:

  • 1 <= s.length <= 300
  • 1 <= wordDict.length <= 1000
  • 1 <= wordDict[i].length <= 20
  • s and wordDict[i] consist of only lowercase English letters.
  • All the strings of wordDict are unique.

Leet Code 139 (Word Break) using a trie with recursion

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 multiple times in the segmentation.

Example 1:

Input: s = "leetcode", wordDict = ["leet","code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".

Example 2:

Input: s = "applepenapple", wordDict = ["apple","pen"]
Output: true
Explanation: Return true because "applepenapple" can be segmented as "apple pen apple". Note that you are allowed to reuse a dictionary word.

Example 3:

Input: s = "catsandog", wordDict = ["cats","dog","sand","and","cat"]
Output: false

Constraints:

  • 1 <= s.length <= 300
  • 1 <= wordDict.length <= 1000
  • 1 <= wordDict[i].length <= 20
  • s and wordDict[i] consist of only lowercase English letters.
  • All the strings of wordDict are unique.
Tweeted twitter.com/StackCodeReview/status/1566078586917888004
Became Hot Network Question
Replaced screen shot of problem description with text. NOTE: This does not invalidate the given answers.
Source Link
Martin R
  • 24.2k
  • 2
  • 38
  • 96

Here is a short example of what this question asks:

LeetCode 139 - Word Break Swift

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 multiple times in the segmentation.

Example 1:

Input: s = "leetcode", wordDict = ["leet","code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".

Example 2:

Input: s = "applepenapple", wordDict = ["apple","pen"]
Output: true
Explanation: Return true because "applepenapple" can be segmented as "apple pen apple".
Note that you are allowed to reuse a dictionary word.

Example 3:

Input: s = "catsandog", wordDict = ["cats","dog","sand","and","cat"]
Output: false  

Constraints:

  • 1 <= s.length <= 300
  • 1 <= wordDict.length <= 1000
  • 1 <= wordDict[i].length <= 20
  • s and wordDict[i] consist of only lowercase English letters.
  • All the strings of wordDict are unique.

Here is a short example of what this question asks:

LeetCode 139 - Word Break Swift

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 multiple times in the segmentation.

Example 1:

Input: s = "leetcode", wordDict = ["leet","code"]
Output: true
Explanation: Return true because "leetcode" can be segmented as "leet code".

Example 2:

Input: s = "applepenapple", wordDict = ["apple","pen"]
Output: true
Explanation: Return true because "applepenapple" can be segmented as "apple pen apple".
Note that you are allowed to reuse a dictionary word.

Example 3:

Input: s = "catsandog", wordDict = ["cats","dog","sand","and","cat"]
Output: false  

Constraints:

  • 1 <= s.length <= 300
  • 1 <= wordDict.length <= 1000
  • 1 <= wordDict[i].length <= 20
  • s and wordDict[i] consist of only lowercase English letters.
  • All the strings of wordDict are unique.
Source Link

Time limit exceeded solving Leet Code 139 using a Trie with recursion

I was attempting to solve LeetCode 139 - Word Break

Here is a short example of what this question asks:

LeetCode 139 - Word Break Swift

I watched some videos saying implementing a trie would be an efficient approach to solve this so I implemented a Trie as follows:

fileprivate class TrieNode {
    var data: Character?
    var isWordEnd = false
    var next = [Character: TrieNode]()
}

fileprivate struct Trie {
    var root = TrieNode()
    
    func insert(_ word: String) {
        var rootNode = root
        
        for char in word {
            rootNode = insertInternal(char, at: rootNode)
        }
        
        rootNode.isWordEnd = true
    }
    
    func insertInternal(_ char: Character, at node: TrieNode) -> TrieNode {
        var nextNode = TrieNode()
        
        if node.next[char] != nil {
            nextNode = node.next[char]!
        }
        
        nextNode.data = char
        node.next[char] = nextNode
        return nextNode
    }
    
    func doesWordExist(_ word: String) -> Bool {
        var rootNode = root
        
        for char in word {
            let nextNode = rootNode.next
            if nextNode[char] == nil {
                return false
            }
            
            rootNode = nextNode[char]!
        }
        
        return rootNode.isWordEnd
    }
}

Then in order to solve the problem, I took the recursion / backtracking approach with the help of the Trie created above in the following way:

func wordBreak(_ s: String, _ wordDict: [String]) -> Bool {
    let trie = Trie()
    
    for word in wordDict {
        trie.insert(word)
    }
    
    return wordBreakInternal(s, wordDict: trie)
}

fileprivate func wordBreakInternal(_ s: String, wordDict: Trie) -> Bool {
    if s.isEmpty { return true }
    
    let leftIndex = s.startIndex
    var rightIndex = s.startIndex
    
    while rightIndex < s.endIndex {
        let word = String(s[leftIndex ... rightIndex])
        
        if wordDict.doesWordExist(word) {
            var nextStartIndex = rightIndex
            s.formIndex(after: &nextStartIndex)
            let nextWord = String(s[nextStartIndex ..< s.endIndex])
            
            if wordBreakInternal(nextWord, wordDict: wordDict) {
                return true
            }
        }
        
        s.formIndex(after: &rightIndex)
    }
    
    return false
}

I feel the solution works in terms of giving the desired output for these test cases:

print(wordBreak("leetcode", ["leet","code"])) // true
print(wordBreak("applepenapple", ["apple","pen"])) // true
print(wordBreak("catsandog", ["cats","dog","sand","and","cat"])) // false
print(wordBreak("aaaaaaa", ["aaaa","aaa"])) // true

However, when a large string is the input:

s = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaab"

wordDict = ["a","aa","aaa","aaaa","aaaaa","aaaaaa","aaaaaaa","aaaaaaaa","aaaaaaaaa","aaaaaaaaaa"]

I get Time Limit Exceeded in my LeetCode submission.

Could someone advice if the optimization needs to be done in my trie implementation or in my backtracking / recursion with some ideas on how to make things more efficient ?