320. Generalized Abbreviation

2018-05-27  本文已影响0人  Nancyberry

Description

Write a function to generate the generalized abbreviations of a word.

**Note: **The order of the output does not matter.

Example:

Input: "word"
Output:
["word", "1ord", "w1rd", "wo1d", "wor1", "2rd", "w2d", "wo2", "1o1d", "1or1", "w1r1", "1o2", "2r1", "3d", "w3", "4"]

Solution

Backtracking, O(n * 2 ^ n), S(n)

Complexity Analysis

Time complexity : O(n * 2^n). For each call to backtrack, it either returns without branching, or it branches into two recursive calls. All these recursive calls form a complete binary recursion tree with 2^n leaves and 2^n - 1 inner nodes. For each leaf node, it needs O(n) time for converting builder to String; for each internal node, it needs only constant time. Thus, the total time complexity is dominated by the leaves. In total that is O(n * 2^n).

Space complexity : O(n). If the return list doesn't count, we only need O(n) auxiliary space to store the characters in StringBuilder and the O(n) space used by system stack. In a recursive program, the space of system stack is linear to the maximum recursion depth which is n in our problem.

题意很好理解,对于word中的每个位置来说,都有缩写和不缩写两种选择,所以总共有2 ^ n中选择。很自然想到利用backtracking来构造所有组合。

class Solution {
    public List<String> generateAbbreviations(String word) {
        List<String> res = new ArrayList<>();
        dfs(word, 0, new StringBuilder(), 0, res);
        return res;
    }
    
    private void dfs(String word, int pos
                     , StringBuilder sb, int count, List<String> res) {
        int originalLen = sb.length();          // keep original sb state
        
        if (pos >= word.length()) {
            sb.append(count > 0 ? count : "");  // don't forget to append count
            res.add(sb.toString());    // cost O(n)!!
        } else {
            // abbreviate
            dfs(word, pos + 1, sb, count + 1, res);
            // don't abbreviate
            sb.append(count > 0 ? count : "");  // append previous abbr chars count  
            sb.append(word.charAt(pos));        // append current char
            dfs(word, pos + 1, sb, 0, res);     // reset count to 0
        }
        
        sb.setLength(originalLen);              // reset sb to original state
    }
}

Bit-manipulation, O(n * 2 ^ n), S(n)

虽然题目里没给定word的长度限制,但我猜测不会很大,因为这道题的时间复杂度一定是指数级的,word太长会TLE。于是可以用bit manipulation去穷举所有选择,这样写也是很清晰的。

class Solution {
    public List<String> generateAbbreviations(String word) {
        List<String> res = new ArrayList<>();
        for (int i = 0; i < (1 << word.length()); ++i) {
            res.add(getAbbr(word, i));
        }
        return res;
    }
    
    private String getAbbr(String word, int bits) {
        StringBuilder sb = new StringBuilder();
        int count = 0;
        
        for (int i = 0; i < word.length(); ++i, bits >>= 1) {
            if ((bits & 1) == 0) {
                sb.append(count > 0 ? count : "")
                    .append(word.charAt(i));
                count = 0;
            } else {
                ++count;
            }
        }
        
        sb.append(count > 0 ? count : "");
        return sb.toString();
    }
}
上一篇下一篇

猜你喜欢

热点阅读