电话号码字母组合的时间复杂度

时间:2021-05-18 11:12:29

标签: recursion complexity-theory depth-first-search analysis backtracking

这是 LeetCode 问题 17:

给定一个包含 2-9 位数字的字符串,返回该数字可以表示的所有可能的字母组合。以任意顺序返回答案。

(https://leetcode.com/problems/letter-combinations-of-a-phone-number/)

以下是我的 DFS 递归代码:

class Solution {
    public static final String[] map = {"", "", "abc", "def", "ghi", "jkl", "mno", "pqrs", "tuv", "wxyz"};
    
    public List<String> letterCombinations(String digits){
        List<String> result = new ArrayList<String>();
        if(digits == null || digits.length() == 0){return result;}
        
        
    
        int curr_index = 0;
        StringBuilder prefix = new StringBuilder("");
        
        update_result(digits, prefix, curr_index, result);
    
        return result;
        
    
    }

    private void update_result(String digits, StringBuilder prefix, int curr_index, List<String> result){
        if(curr_index >= digits.length()){
            result.add(prefix.toString());
            return;
        }
        else{
            String letters = map[ digits.charAt(curr_index) - '0' ];
            for(int i = 0; i < letters.length(); i++){
                prefix.append( letters.charAt(i) );
                update_result(digits, prefix, curr_index+1, result);
                prefix.deleteCharAt(prefix.length() -1);
            }
            return;
        }
        
    }

}

在 LeetCode 解决方案中,它说时间复杂度为 O(n*n^4),其中 n 是输入的长度。除了 n^4 之外,我无法理解剩余的额外 n 来自哪里。

我对代码的分析是:T(n) = O(1) + 4T(n-1)。 (for 循环重复了 4 次,长度减 1。并且在循环中更新前缀 String 需要恒定的时间。)

它解决了 1 + 4 + 4^1+ ... + 4^n = O(4^n)

谁能帮忙解释为什么解决方案说时间复杂度是 O(n*4^n)?

1 个答案:

答案 0 :(得分:0)

我同意你的看法,时间复杂度应该是 O(4^n)。

我有几个想法为什么它可以是 O(n * 4^n):

  1. StringBuilder 的 append 方法在其容量达到阈值时可能需要 O(n) 时间,这意味着将所有元素复制到新数组中。但是在您的情况下,结果字符串的最大长度为 4(来自问题约束),而阈值的默认值为 16(https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html#StringBuilder-java.lang.String-)。由于 4 < 16,所以总是需要 O(1) 时间。

  2. StringBuilder 的 deleteCharAt 方法在最坏的情况下需要 O(n) 时间,因为数组复制。但是在您的情况下,您只删除了最后一个字符,这需要 O(1) 时间。

  3. 使用 String 而不是 StringBuilder,其中一个元素的连接和删除需要 O(n) 时间

相关问题