算法题目-18周-Letter Tile Possibilities

You have a set of tiles, where each tile has one letter tiles[i] printed on it. Return the number of possible non-empty sequences of letters you can make.

Example 1:

Input: "AAB"
Output: 8
Explanation: The possible sequences are "A", "B", "AA", "AB", "BA", "AAB", "ABA", "BAA".

Example 2:

Input: "AAABBC"
Output: 188

Note:

1 <= tiles.length <= 7
tiles consists of uppercase English letters.

使用递归解法

class Solution {
    public int numTilePossibilities(String tiles) {
       char[] chars = tiles.toCharArray();
       List cahrArray = new LinkedList();
       for(int i=0;i<chars.length;i++){
           cahrArray.add(chars[i]);
       }
       Map strMap = new HashMap();
       String str = "";
       checkStr( str, strMap, cahrArray);

       return strMap.size();
    }

    public void checkStr(String str, Map strMap, List chars){

        if(chars.size()!=0){
            for(int i=0;i<chars.size();i++){
                char s = (char)chars.get(i);
                String newstr = str + s;
                strMap.put(newstr,null);
                chars.remove(i);
                checkStr(newstr,strMap,chars);
                chars.add(i,s);
            }
        }

    }
}

效果不理想,速度很慢
Runtime: 25 ms, faster than 32.91% of Java online submissions for Letter Tile Possibilities.
Memory Usage: 38.3 MB, less than 100.00% of Java online submissions for Letter Tile Possibilities.

优化一:将LinkedList修改为ArrayList,也就快乐一点点
Runtime: 20 ms, faster than 39.12% of Java online submissions for Letter Tile Possibilities.
Memory Usage: 36.8 MB, less than 100.00% of Java online submissions for Letter Tile Possibilities.

优化二:判断重复前缀不需要递归

   public void checkStr(String str, Map strMap, List chars){

        if(chars.size()!=0){
            for(int i=0;i<chars.size();i++){
                char s = (char)chars.get(i);
                String newstr = str + s;
                if(strMap.containsKey(newstr)){
                  continue;
                }
                strMap.put(newstr,null);
                chars.remove(i);
                checkStr(newstr,strMap,chars);
                chars.add(i,s);
            }
        }
}

Runtime: 15 ms, faster than 45.99% of Java online submissions for Letter Tile Possibilities.
Memory Usage: 38.3 MB, less than 100.00% of Java online submissions for Letter Tile Possibilities.

目前发现网友最优算法
思路:使用26字母的数组统计字符出现次数,大致原来跟我设计差不多,通过对应字母--和++实现使用和还原。
但是目前疑问就是为什么不判断重复字符串问题呢?直接就总返回值+1?
答案:其实很简单,由于采用该数组模式,相同字母只会取一次作为前缀拼接。
这个相当于我们之前Map判断是否存在一样。

    public int numTilePossibilities(String tiles) {
        int[] count = new int[26];
        for (char c : tiles.toCharArray()) count[c - 'A']++;
        return dfs(count);
    }
    
    int dfs(int[] arr) {
        int sum = 0;
        for (int i = 0; i < 26; i++) {
            if (arr[i] == 0) continue;
            sum++;
            arr[i]--;
            sum += dfs(arr);
            arr[i]++;
        }
        return sum;
    }

Runtime: 1 ms, faster than 99.15% of Java online submissions for Letter Tile Possibilities.
Memory Usage: 34.2 MB, less than 100.00% of Java online submissions for Letter Tile Possibilities.

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容