【问题标题】:What's the time complexity of this recursive algorithm这个递归算法的时间复杂度是多少
【发布时间】:2016-09-15 20:17:54
【问题描述】:

这是一道算法题:

给定一个字符串 s 和一个单词字典 dict,在 s 中添加空格 构造一个句子,其中每个单词都是有效的字典单词。

返回所有可能的句子。

例如,给定 s = "catsanddog", dict = ["cat", "cats", "and", “沙子”、“狗”]。

一个解决方案是["cats and dog", "cat sand dog"]。

解决方案如下,但我很难确定该解决方案的时间复杂度。谁能给我一些提示,特别是如果面试官在面试中问到这个时间复杂度,有没有一种不需要太多数学的快速方法来找到它?

public class Solution {
    Map<String,List<String>> map = new HashMap();
    public List<String> wordBreak(String s, Set<String> wordDict) {
        List<String> res = new ArrayList<String>();
        if(s == null || s.length() == 0) {
            return res;
        }
        if(map.containsKey(s)) {
            return map.get(s);
        }
        if(wordDict.contains(s)) {
            res.add(s);
        }
        for(int i = 1 ; i < s.length() ; i++) {
            String t = s.substring(i);
            if(wordDict.contains(t)) {
                List<String> temp = wordBreak(s.substring(0 , i) , wordDict);
                if(temp.size() != 0) {
                    for(int j = 0 ; j < temp.size() ; j++) {
                        res.add(temp.get(j) + " " + t);
                    }
                }
            }
        }
        map.put(s , res);
        return res;
    }
}

【问题讨论】:

  • 字典可以包含不是给定字符串s的子字符串的字符串吗?
  • @PEF 可以。

标签: java algorithm time-complexity big-o


【解决方案1】:

时间复杂度为O(2^n * n)

此类分词的最大数量为2^(n-1),其中bijection 到长度为n-1 的二进制向量:对于两个字符之间的每个空格,您可以在此处分词(向量中的1)或不是(向量中的0),给你2^(n-1)这样可能的词。

由于创建了每个字符串,计算其哈希并将其添加到集合中是O(n)(子字符串的长度),你得到O(2^n * n)

你得到最坏的情况:

dict = [a, aa, aaa, aaaa, ....]
s = "aaaaaaaaa...a"

您的map 使用memoization 确保您不会重复工作。 (没有它,复杂性将是n 的阶乘,但使用它可以避免重复工作,例如从头开始重新计算“aaa...a|a|a”和“aa...a|aa”的前缀

【讨论】:

  • 添加注释以防有人疑惑:O(2^n) 和 O(2^(n-1)) 是同一个复杂度类。
  • 感谢您的解释。从你的分析看来,对于这种递归算法,其时间复杂度的计算可能不是逐行分析代码,而是从问题本身来的,对吗?
  • @Leo 是两者的结合。代码也被分析以确保没有双重处理。既然是这样,通过找到最坏的例子,你可以得到复杂度
猜你喜欢
  • 1970-01-01
  • 2016-01-14
  • 2015-11-29
  • 2019-05-08
  • 2015-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多