1079. 活字印刷

class Solution {
public:
    set<string> s;
    bool vis[10];
    void dfs(int k, string tiles, string str)
    {
        if(k == 0)
            s.insert(str);
        int len = tiles.length();
        for(int i = 0; i < len; i++)
        {
            if(vis[i]) continue;
            vis[i] = 1;
            dfs(k - 1, tiles, str + tiles[i]);
            vis[i] = 0;
        }
    }
    int numTilePossibilities(string tiles) {
        int len = tiles.length();
        for(int i = 1; i <= len; i++)
        {
            memset(vis, 0, sizeof(vis));
            dfs(i, tiles, "");
        }
        return s.size();
    }
};
View Code

dfs

 

3个月后又重写了一遍 这次时间100%

用有重复元素的全排列

M!的意思是M个元素总共的全排列。
由于a1有N1个元素,所以N1个元素的全排是重复的。
a2,an同上。
得出最后的结果M!/(N1!*N2!*...*Nn!)

 

class Solution {
public:
    vector<int> v;
    vector<int> tmp;
    int cnt[30], ans, jc[8];

    int cal()
    {
        int len = tmp.size();
        int ret1 = 0, ret2 = 1;
        for(int i = 0; i < len; i++)
        {
            ret1 += tmp[i];
            ret2 *= jc[tmp[i]];
        }
        return jc[ret1] / ret2;
    }

    void dfs(int k, int x)
    {
        if(x > v.size()) return;
        if(x == v.size() && k != 0) return;
        if(k == 0)
        {
            ans += cal();
            return;
        }
        for(int i = 0; i <= cnt[v[x]]; i++)
        {
            if(i != 0) tmp.push_back(i);
            dfs(k - i, x + 1);
            if(i != 0) tmp.pop_back();
        }
    }

    int numTilePossibilities(string tiles) {
        jc[1] = 1;
        for(int i = 2; i <= 7; i++)
            jc[i] = jc[i - 1] * i;
        memset(cnt, 0, sizeof(cnt));
        int len = tiles.length();
        for(int i = 0; i < len; i++)
        {
            if(cnt[tiles[i] - 'A'] == 0) v.push_back(tiles[i] - 'A');
            cnt[tiles[i] - 'A']++;
        }
        int ret = 0;
        for(int i = 1; i <= len - 1; i++)
        {
            ans = 0;
            dfs(i, 0);
            ret += ans;
        }
        int ret1 = len, ret2 = 1;
        for(int i = 0; i < v.size(); i++)
        {
            ret2 *= jc[cnt[v[i]]];
        }

        return ret + jc[ret1] / ret2;

    }
};

 

posted @ 2021-10-15 23:35  WTSRUVF  阅读(19)  评论(0编辑  收藏  举报