modify code

pull/6/head
左程云 4 years ago
parent 8f754ac742
commit 68af47bb88

@ -39,31 +39,26 @@ public class Code01_RobotWalk {
// 走向左、走向右是截然不同的方法,所以总方法数要都算上
return walk(N, cur + 1, rest - 1, P) + walk(N, cur - 1, rest - 1, P);
}
public static int waysCache(int N, int M, int K, int P) {
// 参数无效直接返回0
if (N < 2 || K < 1 || M < 1 || M > N || P < 1 || P > N) {
return 0;
}
int[][] dp = new int[N+1][K+1];
for(int row = 0; row <= N; row++) {
for(int col = 0; col <= K; col++) {
int[][] dp = new int[N + 1][K + 1];
for (int row = 0; row <= N; row++) {
for (int col = 0; col <= K; col++) {
dp[row][col] = -1;
}
}
return walkCache(N, M, K, P,dp);
return walkCache(N, M, K, P, dp);
}
// HashMap<String, Integer> (19,100) "19_100"
// HashMap<String, Integer> (19,100) "19_100"
// 我想把所有cur和rest的组合返回的结果加入到缓存里
public static int walkCache(int N, int cur, int rest, int P, int[][] dp) {
if(dp[cur][rest] != -1) {
if (dp[cur][rest] != -1) {
return dp[cur][rest];
}
if (rest == 0) {
@ -75,22 +70,12 @@ public class Code01_RobotWalk {
return dp[cur][rest];
}
if (cur == N) {
dp[cur][rest] =walkCache(N, N - 1, rest - 1, P,dp);
dp[cur][rest] = walkCache(N, N - 1, rest - 1, P, dp);
return dp[cur][rest];
}
dp[cur][rest] = walkCache(N, cur + 1, rest - 1, P,dp)
+ walkCache(N, cur - 1, rest - 1, P, dp);
dp[cur][rest] = walkCache(N, cur + 1, rest - 1, P, dp) + walkCache(N, cur - 1, rest - 1, P, dp);
return dp[cur][rest];
}
public static int ways2(int N, int M, int K, int P) {
// 参数无效直接返回0

@ -1,6 +1,6 @@
package class18;
public class Code03_Knapsack {
public class Code02_Knapsack {
public static int getMaxValue(int[] w, int[] v, int bag) {
return process(w, v, 0, 0, bag);
@ -44,7 +44,7 @@ public class Code03_Knapsack {
int p1 = process(w, v, index + 1, rest);
int p2 = -1;
int p2Next = process(w, v, index + 1, rest - w[index]);
if(p2Next!=-1) {
if (p2Next != -1) {
p2 = v[index] + p2Next;
}
return Math.max(p1, p2);
@ -56,9 +56,9 @@ public class Code03_Knapsack {
// dp[N][...] = 0
for (int index = N - 1; index >= 0; index--) {
for (int rest = 0; rest <= bag; rest++) { // rest < 0
int p1 = dp[index+1][rest];
int p1 = dp[index + 1][rest];
int p2 = -1;
if(rest - w[index] >= 0) {
if (rest - w[index] >= 0) {
p2 = v[index] + dp[index + 1][rest - w[index]];
}
dp[index][rest] = Math.max(p1, p2);

@ -1,152 +0,0 @@
package class18;
import java.util.Arrays;
import java.util.HashMap;
public class Code02_StickersToSpellWord {
public static int minStickers1(String[] stickers, String target) {
int n = stickers.length;
int[][] map = new int[n][26];// stickers -> [26] [26] [26]
for (int i = 0; i < n; i++) {
char[] str = stickers[i].toCharArray();
for (char c : str) {
map[i][c - 'a']++;
}
}
HashMap<String, Integer> dp = new HashMap<>();
dp.put("", 0);
return process1(dp, map, target);
}
// dp 傻缓存如果t已经算过了直接返回dp中的值
// t 剩余的目标
// 0..N每一个字符串所含字符的词频统计
// 返回值是-1map 中的贴纸 怎么都无法rest
public static int process1(
HashMap<String, Integer> dp,
int[][] map,
String rest) {
if (dp.containsKey(rest)) {
return dp.get(rest);
}
// 以下就是正式的递归调用过程
int ans = Integer.MAX_VALUE; // ans -> 搞定rest使用的最少的贴纸数量
int n = map.length; // N种贴纸
int[] tmap = new int[26]; // tmap 去替代 rest
char[] target = rest.toCharArray();
for (char c : target) {
tmap[c - 'a']++;
}
for (int i = 0; i < n; i++) {
// 枚举当前第一张贴纸是谁?
if (map[i][target[0] - 'a'] == 0) {
continue;
}
StringBuilder sb = new StringBuilder();
// i 贴纸, j 枚举a~z字符
for (int j = 0; j < 26; j++) { //
if (tmap[j] > 0) { // j这个字符是target需要的
for (int k = 0; k < Math.max(0, tmap[j] - map[i][j]); k++) {
sb.append((char) ('a' + j));
}
}
}
// sb -> i
String s = sb.toString();
int tmp = process1(dp, map, s);
if (tmp != -1) {
ans = Math.min(ans, 1 + tmp);
}
}
// ans 系统最大 rest
dp.put(rest, ans == Integer.MAX_VALUE ? -1 : ans);
return dp.get(rest);
}
public static int minStickers2(String[] stickers, String target) {
int n = stickers.length;
int[][] map = new int[n][26];
for (int i = 0; i < n; i++) {
char[] str = stickers[i].toCharArray();
for (char c : str) {
map[i][c - 'a']++;
}
}
char[] str = target.toCharArray();
int[] tmap = new int[26];
for (char c : str) {
tmap[c - 'a']++;
}
HashMap<String, Integer> dp = new HashMap<>();
int ans = process2(map, 0, tmap, dp);
return ans;
}
public static int process2(int[][] map, int i, int[] tmap, HashMap<String, Integer> dp) {
StringBuilder keyBuilder = new StringBuilder();
keyBuilder.append(i + "_");
for (int asc = 0; asc < 26; asc++) {
if (tmap[asc] != 0) {
keyBuilder.append((char) (asc + 'a') + "_" + tmap[asc] + "_");
}
}
String key = keyBuilder.toString();
if (dp.containsKey(key)) {
return dp.get(key);
}
boolean finish = true;
for (int asc = 0; asc < 26; asc++) {
if (tmap[asc] != 0) {
finish = false;
break;
}
}
if (finish) {
dp.put(key, 0);
return 0;
}
if (i == map.length) {
dp.put(key, -1);
return -1;
}
int maxZhang = 0;
for (int asc = 0; asc < 26; asc++) {
if (map[i][asc] != 0 && tmap[asc] != 0) {
maxZhang = Math.max(maxZhang, (tmap[asc] / map[i][asc]) + (tmap[asc] % map[i][asc] == 0 ? 0 : 1));
}
}
int[] backup = Arrays.copyOf(tmap, tmap.length);
int min = Integer.MAX_VALUE;
int next = process2(map, i + 1, tmap, dp);
tmap = Arrays.copyOf(backup, backup.length);
if (next != -1) {
min = next;
}
for (int zhang = 1; zhang <= maxZhang; zhang++) {
for (int asc = 0; asc < 26; asc++) {
tmap[asc] = Math.max(0, tmap[asc] - (map[i][asc] * zhang));
}
next = process2(map, i + 1, tmap, dp);
tmap = Arrays.copyOf(backup, backup.length);
if (next != -1) {
min = Math.min(min, zhang + next);
}
}
int ans = min == Integer.MAX_VALUE ? -1 : min;
dp.put(key, ans);
return ans;
}
public static void main(String[] args) {
String[] arr = {"aaaa","bbaa","ccddd"};
String str = "abcccccdddddbbbaaaaa";
System.out.println(minStickers1(arr, str));
System.out.println(minStickers2(arr, str));
}
}

@ -1,6 +1,6 @@
package class18;
public class Code04_CardsInLine {
public class Code03_CardsInLine {
public static int win1(int[] arr) {
if (arr == null || arr.length == 0) {

@ -1,6 +1,6 @@
package class18;
public class Code05_ConvertToLetterString {
public class Code04_ConvertToLetterString {
public static int number(String str) {
if (str == null || str.length() == 0) {

@ -0,0 +1,140 @@
package class18;
import java.util.HashMap;
// 本题测试链接https://leetcode.com/problems/stickers-to-spell-word
public class Code05_StickersToSpellWord {
public static int minStickers1(String[] stickers, String target) {
int ans = process1(stickers, target);
return ans == Integer.MAX_VALUE ? -1 : ans;
}
public static int process1(String[] stickers, String target) {
if (target.length() == 0) {
return 0;
}
int min = Integer.MAX_VALUE;
for (String first : stickers) {
String rest = minus(target, first);
if (rest.length() != target.length()) {
min = Math.min(min, process1(stickers, rest));
}
}
return min + (min == Integer.MAX_VALUE ? 0 : 1);
}
public static String minus(String s1, String s2) {
char[] str1 = s1.toCharArray();
char[] str2 = s2.toCharArray();
int[] count = new int[26];
for (char cha : str1) {
count[cha - 'a']++;
}
for (char cha : str2) {
count[cha - 'a']--;
}
StringBuilder builder = new StringBuilder();
for (int i = 0; i < 26; i++) {
if (count[i] > 0) {
for (int j = 0; j < count[i]; j++) {
builder.append((char) (i + 'a'));
}
}
}
return builder.toString();
}
public static int minStickers2(String[] stickers, String target) {
int N = stickers.length;
// 关键优化(用词频表替代贴纸数组)
int[][] counts = new int[N][26];
for (int i = 0; i < N; i++) {
char[] str = stickers[i].toCharArray();
for (char cha : str) {
counts[i][cha - 'a']++;
}
}
int ans = process2(counts, target);
return ans == Integer.MAX_VALUE ? -1 : ans;
}
public static int process2(int[][] stickers, String t) {
if (t.length() == 0) {
return 0;
}
char[] target = t.toCharArray();
int[] tcounts = new int[26];
for (char cha : target) {
tcounts[cha - 'a']++;
}
int N = stickers.length;
int min = Integer.MAX_VALUE;
for (int i = 0; i < N; i++) {
int[] sticker = stickers[i];
// 关键优化(重要的剪枝!这一步也是贪心!)
if (sticker[target[0] - 'a'] > 0) {
StringBuilder builder = new StringBuilder();
for (int j = 0; j < 26; j++) {
if (tcounts[j] > 0) {
int nums = tcounts[j] - sticker[j];
for (int k = 0; k < nums; k++) {
builder.append((char) (j + 'a'));
}
}
}
String rest = builder.toString();
min = Math.min(min, process2(stickers, rest));
}
}
return min + (min == Integer.MAX_VALUE ? 0 : 1);
}
public static int minStickers3(String[] stickers, String target) {
int N = stickers.length;
int[][] counts = new int[N][26];
for (int i = 0; i < N; i++) {
char[] str = stickers[i].toCharArray();
for (char cha : str) {
counts[i][cha - 'a']++;
}
}
HashMap<String, Integer> dp = new HashMap<>();
dp.put("", 0);
int ans = process3(counts, target, dp);
return ans == Integer.MAX_VALUE ? -1 : ans;
}
public static int process3(int[][] stickers, String t, HashMap<String, Integer> dp) {
if (dp.containsKey(t)) {
return dp.get(t);
}
char[] target = t.toCharArray();
int[] tcounts = new int[26];
for (char cha : target) {
tcounts[cha - 'a']++;
}
int N = stickers.length;
int min = Integer.MAX_VALUE;
for (int i = 0; i < N; i++) {
int[] sticker = stickers[i];
if (sticker[target[0] - 'a'] > 0) {
StringBuilder builder = new StringBuilder();
for (int j = 0; j < 26; j++) {
if (tcounts[j] > 0) {
int nums = tcounts[j] - sticker[j];
for (int k = 0; k < nums; k++) {
builder.append((char) (j + 'a'));
}
}
}
String rest = builder.toString();
min = Math.min(min, process3(stickers, rest, dp));
}
}
int ans = min + (min == Integer.MAX_VALUE ? 0 : 1);
dp.put(t, ans);
return ans;
}
}
Loading…
Cancel
Save