(leetcode问题:139。单词断路)Java解决方案超时 - 回溯解决方案
问题的链接: 139。单词断开 下面的解决方案无法通过所有测试用例并导致超时。我想使用回溯来解决这个问题,但是看来它不起作用。谁能告诉我我的代码中有什么问题? 此外,这里的解决方案的时间复杂性为O(2^n + n^2)。如何优化它以使其通过所有测试用例?多谢!我真的很感激。
class Solution {
boolean found;
public boolean wordBreak(String s, List<String> wordDict) {
backtrack(s, wordDict, 0);
return found;
}
public void backtrack(String s, List<String> wordDict, int index){
if(found == true) return;
if(index == s.length()){
found = true;
return;
}
for(int len = 1; index + len <= s.length(); len++){
String prefix = s.substring(index, index + len);
if(wordDict.contains(prefix)){
backtrack(s, wordDict, index + len);
}
}
}
}
The link to the question: 139. Word Break
The solution below can not passed all the test cases and lead to timeout. I want to use backtracking to solve this question, however it seems that it doesn't work. Can anyone tell me what's wrong in my code?
Besides, the solution here its time complexity is O(2^n + n^2). How can I optimize it so that it can pass all test cases? Thanks a lot! I really appreciate it.
class Solution {
boolean found;
public boolean wordBreak(String s, List<String> wordDict) {
backtrack(s, wordDict, 0);
return found;
}
public void backtrack(String s, List<String> wordDict, int index){
if(found == true) return;
if(index == s.length()){
found = true;
return;
}
for(int len = 1; index + len <= s.length(); len++){
String prefix = s.substring(index, index + len);
if(wordDict.contains(prefix)){
backtrack(s, wordDict, index + len);
}
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
某些问题:
尝试 all 索引和所有长度匹配所有单词都在做得太多。这些测试中的许多将永远不会成功。例如,如果单词列表仅具有大小为3和4的单词,则仍然与它们相比,其长度大于4是没有意义的。想象一下字符串输入长度为1000的处理。
s
的其余部分中没有什么可用的,您将回溯并尝试其他单词。如果您碰巧找到其他单词以导致索引10,那么尝试再次覆盖其余部分 是没有意义的。众所周知,它将行不通。因此,您应该从尝试未成功的地方注册索引,以便如果您再次到达该索引,就不会重做递归搜索。您可以为此使用布尔数组,每个索引都有一个布尔值。当发现找到时,而不是返回时,当找到是真的时,请突破循环,避免任何进一步的递归调用。
使用实例成员使用实例成员是可以的,但是测试框架将在
solution>解决方案
的同一实例上运行您的代码,以便找到的值
重置为的值< /code>在两个测试之间没有重置为
false
。您必须将false
每次调用函数时。但是,我建议您使您的函数返回 boolean值,因此您根本不需要该实例成员。这是使用上述备注的扰流板解决方案:
Some issues:
Trying at all indices and all lengths to match all words is doing way too much. Many of those tests will never succeed. For instance, if the list of words only has words of sizes 3 and 4, it makes no sense to still compare with them for lengths that are greater than 4. Imagine the processing when the string input has a length of 1000.
When two words have been matched to get to index 10, but nothing works to cover for the remaining part of
s
, you'll backtrack and try other words. If you then happen to find other words to lead up to index 10, it makes no sense to try to cover for the remaining part again. It is already known that it will not work. So you should register the index from where an attempt was not successful, so that if ever you arrive at that index again, you'll not redo the recursive search. You can use a boolean array for this, with a boolean for each index.Instead of returning when
found
is already true, break out of the loop whenfound
is true, avoiding any further recursive calls.Using an instance member
found
is fine, but the test framework will run your code on the same instance ofSolution
, so that the value offound
is not reset tofalse
between two tests. You must resetfound
tofalse
every time the function is called. I would however suggest to make your function return that boolean value, so you don't need that instance member at all.Here is a spoiler solution using the above remarks:
通过添加打印语句可以轻松地注意到解决方案的问题。
在这里,如果执行示例测试案例,
您会注意到:
如您所见(打印语句3和5)同一执行正在发生两次。现在想象一下这是一个非常长的答案。
The problem of your solution can be easily noticed by adding a print statement.
Here if you execute example test case
You will notice:
As you can see (print statements 3 and 5) same execution is happening two times. Now imagine this with a really long answer.
谢谢大家回答我的问题!我通过回忆修复并优化了解决方案。现在,解决方案可以通过Leetcode上的所有测试用例传递。
Thanks for everyone that reply my question!! I fixed and optimized my solution with memoization. Now, the solution can pass all the test cases on leetcode.