算法

1079. 活字印刷

2023-05-19  本文已影响0人  红树_

参考1079. 活字印刷 - 力扣(Leetcode),难度分1741。

题目

你有一套活字字模 tiles,其中每个字模上都刻有一个字母 tiles[i]。返回你可以印出的非空字母序列的数目。

注意:本题中,每个活字字模只能使用一次。

输入:"AAB"
输出:8
解释:可能的序列为 "A", "B", "AA", "AB", "BA", "AAB", "ABA", "BAA"。
输入:"AAABBC"
输出:188
输入:"V"
输出:1

解题思路

哈希表+滚动哈希

class Solution {

    HashSet<Integer> set;
    char[] tc;
    public int numTilePossibilities(String tiles) {
        //考虑使用哈希表
        set = new HashSet<>();
        tc = tiles.toCharArray();
        //只考虑数量 使用滚动哈希优化P=131或37都可通过测试用例
        dfs(0, 0);
        return set.size()-1;
    }

    //pre前面已选字符
    void dfs(int hash,int pre) {
        set.add(pre);
        //选或不选
        for(int i = 0; i < tc.length; i++) {
            if((hash>>i&1) == 0){ //该位置可以选择
                dfs(hash | (1 << i),pre*131 + tc[i]);
            }
        }
    }
}

复杂度分析

计数+回溯

class Solution {
    public int numTilePossibilities(String tiles) {
        int[] cnt = new int[26]; //计数
        for (char c : tiles.toCharArray()) {
            ++cnt[c - 'A'];
        }
        return dfs(cnt);
    }

    private int dfs(int[] cnt) {
        int res = 0;
        for (int i = 0; i < cnt.length; ++i) {
            if (cnt[i] > 0) {
                ++res;
                --cnt[i];
                res += dfs(cnt);
                ++cnt[i]; //回溯 恢复现场
            }
        }
        return res;
    }
}

复杂度分析

上一篇下一篇

猜你喜欢

热点阅读