题目来源:力扣

题目描述:

你有一套活字字模 tiles,其中每个字模上都刻有一个字母 tiles[i]。返回你可以印出的非空字母序列的数目。
====================================================
输入:“AAB”
输出:8
解释:可能的序列为 “A”, “B”, “AA”, “AB”, “BA”, “AAB”, “ABA”, “BAA”。
===================================================
提示:
1 <= tiles.length <= 7
tiles 由大写英文字母组成

审题:

本题有点类似与排列组合中的排列问题,其中子集的大小可以为任意大小但非空.本题主要的复杂性在于字符串中可能存在重复字符.

对于这类题目,大都可以使用回溯的思路解决,区别在于考虑每一步的可能选择子集.如果字符串中不包含重复值,则我们的下一步可以选择任意未被选中的字符,或者不选(在第一步我们必须选择一个值,因为最终结果字符串不能为空).而由于存在重复字符,因此我们选择第一个字符’A’与第二个字符’A’对最终的结果是没有任何区别的,如果按照原有思路,则会存在重复计数.因此,对于存在重复字符的字符串,我们的每一步选择只能在所有未被选择且不重复的字符中选择.

可以使用键值对结构保存字符串中每一个字符的个数,基于此,我们的每一步选择即为所有值不为空的键,或者空集(在第一步不能选择空);当我们选择空集时,表示当前选择结束,计数+1;

java算法:

class Solution {Map<Character, Integer> map = new HashMap<>();int totalNum;//当前可选的字符集合为所有至不为0的键,或者不选任何元素,直接返回private void dfs(boolean end){//如果构建结束,则计数+1if(end){totalNum++;return;}for(Character k: map.keySet()){if(map.get(k) != 0){System.out.println(k);map.put(k, map.get(k)-1); //入栈,该键对应的值减1dfs(false); //由于我们在该步选择了字符k,所以选择并未结束,传入falsemap.put(k, map.get(k)+1); //退栈,该键对应的值加1}}//从第二步起,在每一步,我们均可以选择空集,表示当前构造子集结束.dfs(true);}public int numTilePossibilities(String tiles) {//统计字符串中各字符数量for(int i = 0; i < tiles.length(); i++){char c = tiles.charAt(i);if(map.containsKey(c))map.put(c, map.get(c)+1);elsemap.put(c, 1);}//由于第一步不能选择空集,因此第一步单独考虑for(char c: map.keySet()){map.put(c, map.get(c)-1);dfs(false);map.put(c, map.get(c)+1);}return totalNum;}
}

更新:

在参考其他人关于此题的题解后,发现我最初的思路很不是很简洁,存在很多可以优化的地方.
1.首先由于原始字符串仅有大写字符组成,因此我们可是使用整数数组保存每一个字符出现的次数来代替代码中的HashMap结构.经对比,使用整数数组能够大幅减少程序执行时间.
2.其次,回溯的思路可以重新设计.我们每一步的可选集合为所有值不为0的键,在选完当前值后,我们可以终止选择,此时总的方案数加1,我们也可以继续进行下一个字符的选择,此时我们递归调用,将当前选中键的值减1,在递归退出后,将该键对应的值加1.每次递归调用的结果为当前剩余字符中可能的选择结果.如果当前剩余字符为空,则返回0.

class Solution {private int dfs(int[] charNum){int res = 0;for(int i = 0; i < charNum.length; i++){if(charNum[i] != 0){res++;charNum[i]--;res += dfs(charNum);charNum[i]++;}}return res;}public int numTilePossibilities(String tiles) {int[] charNum = new int[26];//统计字符串中各字符数量for(int i = 0; i < tiles.length(); i++){charNum[tiles.charAt(i)-'A']++;}return dfs(charNum);}
}

leetcode:活字印刷相关推荐

  1. Java实现:LeetCode活字印刷

    题目: 代码: public class text2 {public static void main(String[] args) {Scanner sc=new Scanner(System.in ...

  2. 【leetcode】1079.活字印刷

    活字印刷 问题描述 问题分析 解决方案 问题描述 活字印刷 你有一套活字字模 tiles,其中每个字模上都刻有一个字母 tiles[i].返回你可以印出的非空字母序列的数目. 注意:本题中,每个活字字 ...

  3. Leetcode.1079 活字印刷

    题目链接 Leetcode.1079 活字印刷 Rating : 1741 题目描述 你有一套活字字模 tiles,其中每个字模上都刻有一个字母 tiles[i].返回你可以印出的非空字母序列的数目. ...

  4. leetcode —— 1079. 活字印刷

    你有一套活字字模 tilestilestiles,其中每个字模上都刻有一个字母 tiles[i]tiles[i]tiles[i].返回你可以印出的非空字母序列的数目. 示例 1: 输入:"A ...

  5. Leetcode刷题java之1079. 活字印刷

    可参考本博客回溯法专栏的最后一条的回溯法框架 https://blog.csdn.net/qq_41901915/article/details/104113330 执行结果: 通过 显示详情 执行用 ...

  6. LeetCode 1079 活字印刷

    1079. 活字印刷 题目 思路 先计数,dfs组合枚举. 代码 class Solution {public:int numTilePossibilities(string tiles) {unor ...

  7. Leetcode 1079:活字印刷

    题目描述 你有一套活字字模 tiles,其中每个字模上都刻有一个字母 tiles[i].返回你可以印出的非空字母序列的数目. 示例 1: 输入:"AAB" 输出:8 解释:可能的序 ...

  8. LeetCode题解(1079):活字印刷(Python)

    题目:原题链接(中等) 标签:回溯算法 解法 时间复杂度 空间复杂度 执行用时 Ans 1 (Python) O(N!)O(N!)O(N!) O(N!)O(N!)O(N!) 136ms (43.48% ...

  9. LeetCode 1079. 活字印刷

    想看更多算法题,可以扫描上方二维码关注我微信公众号"数据结构和算法",截止到目前我已经在公众号中更新了500多道算法题,其中部分已经整理成了pdf文档,截止到目前总共有1000多页 ...

最新文章

  1. DLL: 一种直接法的激光雷达定位方案
  2. php 读取php.ini,php7 读取php.ini[4]
  3. 看 600 页技术书可以坚持,剩 60 页就坚持不了……| 每日趣闻
  4. 【Flutter】底部导航栏实现 ( BottomNavigationBar 底部导航栏 | BottomNavigationBarItem 导航栏条目 | PageView )
  5. 2019-06-15
  6. 阿里云CDN+OSS完成图片加速
  7. iOS开发网络篇—发送GET和POST请求(使用NSURLSession)
  8. codevs3044 线段树+扫描线
  9. glide 4.0 之后 和圆角裁剪CenterCrop冲突
  10. rslinx连接linux教程,RSLinx Classic软件通讯配置教程
  11. 照片放大模糊怎么变清晰,图片无损放大
  12. 计算机控制理论及应用,计算机控制理论及应用.doc
  13. 学习 opencv 自带示例 stereo_calib(立体相机标定)
  14. Android x86 镜像 安装到 PC 机上
  15. Spring5之IOC容器中IOC操作之Bean管理(二)之p名称空间注入、外部bean、内部bean、级联赋值
  16. 什么是SEM?SEM是否包括SEO?
  17. i7台式电脑配置推荐_专业设计师电脑配置推荐 i7-7700配K2200组装台式电脑配置及报价...
  18. C#【控件篇】按Tab键可以跳转到下个控件(TabIndex、TabStop的设置)
  19. 基于约束的装配设计【CadQuery】
  20. 环境大数据应用“含苞待放”?

热门文章

  1. matlab 调整矩阵形状,在MATLAB中调整3D矩阵(图像)的大小
  2. 嘿嘿 抢到了iphone4
  3. linux这个名字,Linux 今天 24 岁了,他爸爸最初起的名字却不是这个
  4. 苹果id界面无法打开解决方法「iphone技巧」
  5. java实现对pdf文件压缩,拆分,修改水印,添加水印
  6. 【STM32学习笔记】(5)—— STM32工程添加源文件和头文件
  7. [指北针分类信息软件 v1.5.2.1] 全自动分类信息软件+高效稳定建立SEO外部链接
  8. 维基百科,20岁生日快乐
  9. nasm寄存器xmm[0~8使用]
  10. 10以内加减法口诀表