当前位置:网站首页>暴力递归到动态规划 05 (贴纸拼词)
暴力递归到动态规划 05 (贴纸拼词)
2022-07-30 05:04:00 【涛涛英语学不进去】
1. 暴力递归(超时)
public int minStickers(String[] stickers, String target) {
int result = minSticker(stickers, target);
return (result == Integer.MAX_VALUE) ? -1 : result;
}
/** * @param stickers 字符数组 * @param target 目标值 * @return */
public int minSticker(String[] stickers, String target) {
if (target.length() == 0) {
return 0;
}
int min = Integer.MAX_VALUE;
for (int i = 0; i < stickers.length; i++) {
//新的目标串
String minus = minus(target, stickers[i]);
//如果 对 原串 有改变,即新串变短了
if (minus.length() != target.length()) {
min = Math.min(min, minSticker(stickers, minus));
}
}
return min + (min == Integer.MAX_VALUE ? 0 : 1);
}
/** * 返回 s1 - s2 * * @param s1 大串 需要保留的 * @param s2 小串 * @return */
public String minus(String s1, String s2) {
char[] charS1 = s1.toCharArray();
char[] charS2 = s2.toCharArray();
//哈希法
int[] result = new int[26];
for (int i = 0; i < charS1.length; i++) {
result[charS1[i] - 'a']++;
}
for (int i = 0; i < charS2.length; i++) {
result[charS2[i] - 'a']--;
}
StringBuilder sb = new StringBuilder();
for (int i = 0; i < result.length; i++) {
if (result[i] > 0) {
for (int j = 0; j < result[i]; j++) {
sb.append((char) (i + 'a'));
}
}
}
return String.valueOf(sb);
}
2. 暴力递归 + 剪枝 (超时)
public int minStickers2(String[] stickers, String target) {
int[][] str = new int[stickers.length][26];
// 贴纸词频统计
for (int i = 0; i < stickers.length; i++) {
for (int j = 0; j < stickers[i].length(); j++) {
str[i][stickers[i].charAt(j) - 'a']++;
}
}
int result = minSticker2(str, target);
return (result == Integer.MAX_VALUE) ? -1 : result;
}
/** * @param stickers 字符数组 * @param target 目标值 * @return */
public int minSticker2(int[][] stickers, String target) {
if (target.length() == 0) {
return 0;
}
//目标串词频统计
int[] targetArr = new int[26];
// 贴纸词频统计 不一定开头为 a
for (int i = 0; i < target.length(); i++) {
targetArr[target.charAt(i) - 'a']++;
}
int min = Integer.MAX_VALUE;
for (int i = 0; i < stickers.length; i++) {
int[] sticker = stickers[i];
//如果这个目标串的首元素
if (sticker[target.charAt(0) - 'a'] > 0) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < 26; j++) {
//在目标串中找元素,不过匹配串位置有没有,先减了再说
if (targetArr[j] > 0) {
int nums = targetArr[j] - sticker[j];
for (int k = 0; k < nums; k++) {
//重新生成新的目标串 每个字母相减后剩余的目标串的元素
sb.append((char) (j + 'a'));
}
}
}
min = Math.min(min, minSticker2(stickers, String.valueOf(sb)));
}
}
return min + (min == Integer.MAX_VALUE ? 0 : 1);
}
public int minStickers3(String[] stickers, String target) {
int[][] str = new int[stickers.length][26];
// 贴纸词频统计
for (int i = 0; i < stickers.length; i++) {
for (int j = 0; j < stickers[i].length(); j++) {
str[i][stickers[i].charAt(j) - 'a']++;
}
}
HashMap<String, Integer> dp = new HashMap<String, Integer>();
int result = minSticker3(str, target,dp);
return (result == Integer.MAX_VALUE) ? -1 : result;
}
3. 动态规划
第一个比第二个少通过一个测例,第一个 32/101 ; 第二个 33/101
第三个说是加了一个动态规划,其实就是记忆化搜索吧,每次变换后,在map数组中保留结果,下次计算时如果结果算过,直接返回这个结果。
/** * @param stickers 字符数组 * @param target 目标值 * @return */
public int minSticker3(int[][] stickers, String target, HashMap<String, Integer> dp) {
if (target.length() == 0) {
return 0;
}
if (dp.containsKey(target)) {
return dp.get(target);
}
//目标串词频统计
int[] targetArr = new int[26];
// 贴纸词频统计 不一定开头为 a
for (int i = 0; i < target.length(); i++) {
targetArr[target.charAt(i) - 'a']++;
}
int min = Integer.MAX_VALUE;
for (int i = 0; i < stickers.length; i++) {
int[] sticker = stickers[i];
//如果这个目标串的首元素
if (sticker[target.charAt(0) - 'a'] > 0) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < 26; j++) {
//在目标串中找元素,不过匹配串位置有没有,先减了再说
if (targetArr[j] > 0) {
int nums = targetArr[j] - sticker[j];
for (int k = 0; k < nums; k++) {
//重新生成新的目标串 每个字母相减后剩余的目标串的元素
sb.append((char) (j + 'a'));
}
}
}
min = Math.min(min, minSticker3(stickers, String.valueOf(sb),dp));
}
}
dp.put(target, min + (min == Integer.MAX_VALUE ? 0 : 1));
return min + (min == Integer.MAX_VALUE ? 0 : 1);
}

边栏推荐
- 22. Why do you need a message queue?What are the advantages of using the message queue?
- LeetCode Algorithm 2326. 螺旋矩阵 IV
- LeetCode Algorithm 2326. Spiral Matrix IV
- Some understanding of YOLOv7
- Weight line segment tree + line segment tree split/merge + CF1659D
- Hexagon_V65_Programmers_Reference_Manual (14)
- Hexagon_V65_Programmers_Reference_Manual(14)
- Get the local IP and Request's IP
- Shanxi group (enterprises) in the second network security skills competition part problem WP (7)
- KubeMeet Registration | The complete agenda of the "Edge Native" Online Technology Salon has been announced!
猜你喜欢

Hexagon_V65_Programmers_Reference_Manual (11)
Go study notes (84) - Go project directory structure

1315_Use the LOOPBACK simulation mode to test whether the pyserial installation is successful

Using the GPU parallel computing 】 【 OpenCL&OpenCLUtilty GPU parallel computing

L2-025 分而治之

Web page element parsing a tag

Usage of EFR32 as sniffer for Zigbee/Thread

KubeMeet Registration | The complete agenda of the "Edge Native" Online Technology Salon has been announced!

ThinkPHP高仿蓝奏云网盘系统源码/对接易支付系统程序

WPF study notes "WPF Layout Basics"
随机推荐
全流程调度——Azkaban入门与进阶
error: The following untracked working tree files would be overwritten by
KubeMeet Registration | The complete agenda of the "Edge Native" Online Technology Salon has been announced!
2.4 hill sorting
Predictive maintenance scheduling of multiple power equipment based on data-driven fault prediction
GCC Rust is approved to be included in the mainline code base, or will meet you in GCC 13
ThinkPHP高仿蓝奏云网盘系统源码/对接易支付系统程序
Xiamen SenseCore Technology MC3172(1): Introduction and Environment Construction
斐波那契数列的递归优化《备忘录递归》
SVN 查看用户名密码
5. View parsing and template engine
【Verilog】HDLBits题解——Circuits/Combinational Logic
Catch That Cow(详解)
The Double Pointer Problem (Part 1)
go语言学习笔记四
Alibaba Cloud's EasyNLP Chinese text image generation model takes you to become an artist in seconds
双指针问题(下)
mysql isolation level
Detailed explanation of REUSE_ALV_GRID_DISPLAY
05 Detailed explanation of the global configuration file application.properties
