leetcode -- 691. Stickers to Spell Word【动态规划 + 位图使用】
来源:互联网 发布:淘宝买家皇冠号多少钱 编辑:程序博客网 时间:2024/06/07 14:56
题目
We are given N different types of stickers. Each sticker has a lowercase English word on it.
You would like to spell out the given target
string by cutting individual letters from your collection of stickers and rearranging them.
You can use each sticker more than once if you want, and you have infinite quantities of each sticker.
What is the minimum number of stickers that you need to spell out the target
? If the task is impossible, return -1.
Example 1:
Input:
["with", "example", "science"], "thehat"
Output:
3
Explanation:
We can use 2 "with" stickers, and 1 "example" sticker.After cutting and rearrange the letters of those stickers, we can form the target "thehat".Also, this is the minimum number of stickers necessary to form the target string.
Example 2:
Input:
["notice", "possible"], "basicbasic"
Output:
-1
Explanation:
We can't form the target "basicbasic" from cutting letters from the given stickers.
Note:
stickers
has length in the range [1, 50]
.stickers
consists of lowercase English words (without apostrophes).target
has length in the range [1, 15]
, and consists of lowercase English letters.题意
给定一个字符串集合S,以及一个目标字符串T.求使用S中字符串的最小个数,能够满足T需要的字符数。类似于多目标优化的问题(弄清这一类问题如何求解)
背包问题(变形)
给定物品的特点
给定背包的限制
求最小的物品的数量。
分析及解答
参考:(https://discuss.leetcode.com/topic/106368/rewrite-of-contest-winner-s-solution/7)
- 【位图法】因为待匹配串target的数量最多是15个,因此其子集的数量最多有 2^15个,而int类型占用四个字节,能够容纳标识所有target的子集。所以我们可以将target的子集 映射到 int的整型数中。
- 【int 与 target子集之间的映射关系】将int类型分解为二进制的形式后,有些位置为0,有些位置为1.表明在target中哪些位置的字符是否保留(1表示保留)。
- 【动态规划】dp中存储的是得到子集i,需要的最少的单词的数量。
class Solution { public int minStickers(String[] stickers, String target) { int n = target.length(), m = 1 << n; // if target has n chars, there will be m=2^n-1 subset of characters in target int[] dp = new int[m]; for (int i = 0; i < m; i++) dp[i] = Integer.MAX_VALUE; // use index 0 - 2^n-1 as bitmaps to represent each subset of all chars in target dp[0] = 0; // first thing we know is : dp[empty set] requires 0 stickers, for (int i = 0; i < m; i++) { // for every subset i, start from 000...000。(起点这里很重要,因为大的集合往往依赖于小的集合) if (dp[i] == Integer.MAX_VALUE) continue; for (String s : stickers) { // try use each sticker as an char provider to populate 1 of its superset, to do that: int sup = i;//关键代码(下面:在i上面加入一个单词后的效果) for (char c : s.toCharArray()) { // for each char in the sticker, try apply it on a missing char in the subset of target for (int r = 0; r < n; r++) { if (target.charAt(r) == c && ((sup >> r) & 1) == 0) { //如果target中包含字符c , 并且sup中相应位置没有c。 sup |= 1 << r;//在sup中相应位置,加入c,形成新的集合。 break; } } } // after you apply all possible chars in a sticker, you get an superset that take 1 extra sticker than subset // would take, so you can try to update the superset's minsticker number with dp[sub]+1; dp[sup] = Math.min(dp[sup], dp[i] + 1);//判断是否需要替换原来sup中的值。 } } return dp[m - 1] != Integer.MAX_VALUE ? dp[m - 1] : -1; }}
阅读全文
1 0
- leetcode -- 691. Stickers to Spell Word【动态规划 + 位图使用】
- leetcode 691.Stickers to Spell Word
- 691. Stickers to Spell Word
- leetcode 691. Stickers to Spell Word(状压dp)
- LWC 53:691. Stickers to Spell Word
- leetcode691 Stickers to Spell Word 带记忆功能的回溯
- Stickers to Spell Word:多个单词拆拼接成完整以个目标单词所耗最小数目
- [LeetCode] [动态规划] Word Break
- 【LeetCode】Word Break 动态规划
- 【LeetCode】Word Break II 动态规划
- LeetCode练习-动态规划算法-word-break
- leetcode: Word Break 纪念又一次死在动态规划上
- 动态规划——Word Break 拆分词句【LeetCode】
- '动态规划:word-break'
- 动态规划:word-break
- leetcode 140:Word Break II 采用很巧妙的动态规划和DFS联合使用 JAVA源代码实现
- 139. Word Break 动态规划
- [LeetCode] [动态规划] Triangle
- 详解Android中AsyncTask的使用
- 插入排序(java实现)
- springmvc 拦截器 防止重复提交表单
- 1059. C语言竞赛(20)
- CPU三级缓存
- leetcode -- 691. Stickers to Spell Word【动态规划 + 位图使用】
- eclipse怎么设置字体大小
- Android按钮的渐变色的简单实现
- VS2013出现“无法找到“xxx.exe”的调试信息,或者调试信息不匹配”错误解决方案
- 深入理解Java虚拟机(一)
- 软件工程第二章第3题
- java数据结构与算法的基础总结
- Java中缀转后缀表达式
- == equals()问题