leetcode 1079解题报告

1079. 活字印刷【中等】

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

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

示例 1:

输入:“AAB”
输出: 8
解释: 可能的序列为 “A”, “B”, “AA”, “AB”, “BA”, “AAB”, “ABA”, “BAA”。

示例 2:

输入:“AAABBC”
输出: 188


在这里插入图片描述

关于构造全排列的代码请见:

本题看样例输出,既不像子集,也不像排列,但更像排列。

实际上本题求的是在构造***含有重复元素数组全排列***时,统计搜索树上的节点数,看下图一目了然:

在构造全排列时,根据递归的思想:每次只确定当前位置上的元素,递归确定下一个位置上的元素,搜索树上的节点由哪些已经确定的子排列构成。
在这里插入图片描述

上图中除了,根节点之外的所有节点就是使用AAB所能印刷的所有序列。

下面的代码实际上就是递归法构造全排列,不过我们并不是需要真的构造出全排列,而是统计递归次数(也就是搜索树的节点数目),以及需要处理重复元素。

处理办法就是:在递归同一层的循环之中,只考虑首次出现的元素,这样做在搜索树的同一层不会出现重复结点。

private int ans;

    private void swap(char[] chars, int i, int j) {
        char ch = chars[i];
        chars[i] = chars[j];
        chars[j] = ch;
    }

    public void numTilePossibilities(char[] chars, int cur) {

        if (cur == chars.length) return;

        lable:
        for (int i = cur; i < chars.length; i++) {
            
            // 由于构造全排列使用的是交换法
            // 递归过程中数组中的重复元素可能不相邻
            // 因此不能使用 if(i!=cur && chars[i] == chars[i-1]) continue;
            for (int j = cur; j < i; j++) {
                // 递归同一层的循环之中,只考虑首次出现的元素
                if (chars[j] == chars[i]) continue lable;
            }
            ans++;
            if (i != cur) swap(chars, cur, i);
            numTilePossibilities(chars, cur + 1);
            if (i != cur) swap(chars, cur, i);
        }
    }

    public int numTilePossibilities(String tiles) {

        numTilePossibilities(tiles.toCharArray(), 0);
        return ans;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值