pull/3/head
Leo 5 years ago
parent 3548d2a957
commit 6b877671dc

@ -118,6 +118,35 @@ public class PrintStr {
*
*/
static class Permutations{
public static String[] permutation(String s) {
if (s == null || s.length() == 0) {
return new String[]{};
}
List<String> ans = new ArrayList<>();
char[] str = s.toCharArray();
process(str, 0, ans);
return ans.toArray(new String[ans.size()]);
}
private static void process(char[] str, int i, List<String> ans) {
if (i == str.length) {
ans.add(String.valueOf(str));
}else{
for (int j = i; j < str.length; j++) {
swap(str, i, j);
process(str, i + 1, ans);
swap(str, i, j);
}
}
}
private static void swap(char[] str, int i, int j) {
char temp = str[i];
str[i] = str[j];
str[j] = temp;
}
}
@ -169,8 +198,10 @@ public class PrintStr {
List<String> subNoRepeat = SubNoRepeat.subNoRepeat(str);
System.out.println(subNoRepeat.toString());
String[] permutation = PermutationsNoRepeat.permutation(str);
String[] permutation = Permutations.permutation(str);
String[] permutationNoRepeat = PermutationsNoRepeat.permutation(str);
System.out.println(new ArrayList<String>(Arrays.asList(permutation)).toString());
System.out.println(new ArrayList<String>(Arrays.asList(permutationNoRepeat)).toString());
}
}

@ -78,7 +78,27 @@ public class ReverseStackUsingRecursive {
}
}
static class Code3 {
public static void reverse(Stack<Integer> stack) {
if (stack.isEmpty()) {
return;
}
Integer last = f(stack);
reverse(stack);
stack.push(last);
}
private static Integer f(Stack<Integer> stack) {
Integer value = stack.pop();
if (stack.isEmpty()) {
return value;
}
int last = f(stack);
stack.push(value);
return last;
}
}
public static void main(String[] args){
Stack<Integer> stack = new Stack<>();
@ -86,7 +106,7 @@ public class ReverseStackUsingRecursive {
stack.push(2);
stack.push(3);
stack.push(4);
Code2.reverse(stack);
Code3.reverse(stack);
System.out.println(stack);
}

@ -8,6 +8,7 @@ import org.w3c.dom.ranges.Range;
* @ClassName CardsInLine
* @DATE 2021/1/5 11:48
* @Description
* L...R
* arr线
* AB
* AB

@ -7,6 +7,8 @@ import java.awt.event.KeyEvent;
* @ClassName RobotWalk
* @DATE 2021/1/5 4:27
* @Description
*
*
* , start,
* aim,k,
* ?

@ -1,10 +1,145 @@
package leo.class19;
import java.time.OffsetDateTime;
/**
* @author Leo
* @ClassName ConvertToLetterString
* @DATE 2021/1/7 5:19
* @Description
* 1
* 1A2B3C...
* "111:
* "AAA""KA""AK"
* str
*/
public class ConvertToLetterString {
static class Recursion {
public static int number(String s) {
if (s.length() == 0 || s == null) {
return 0;
}
return process(0, s.toCharArray());
}
private static int process(int i, char[] str) {
if (i == str.length) {
return 1;
}
if (str[i] == '0') {
return 0;
}
//当前位置单转
int ans = process(i + 1, str);
//入股不越界,当前位置与下一个位置的和<=26,也计入次数,下一个位置从i+2算
if (i + 1 < str.length && (str[i] - '0') * 10 + (str[i + 1] - '0') <= 26) {
ans += process(i + 2, str);
}
return ans;
}
}
static class Dp {
public static int number(String s) {
if (s == null || s.length() == 0) {
return 0;
}
int n = s.length();
int[] dp = new int[n + 1];
dp[n] = 1;
char[] str = s.toCharArray();
for (int i = n - 1; i >= 0; i--) {
if (str[i] != '0') {
int ans = dp[i + 1];
//入股不越界,当前位置与下一个位置的和<=26,也计入次数,下一个位置从i+2算
if (i + 1 < str.length && (str[i] - '0') * 10 + (str[i + 1] - '0') <= 26) {
ans += dp[i + 2];
}
dp[i] = ans;
}
}
return dp[0];
}
}
static class Recursion1 {
public static int number(String s) {
if (s == null || s.length() == 0) {
return 0;
}
return process(0, s.toCharArray());
}
private static int process(int i, char[] str) {
if (i == str.length) {
return 1;
}
if (str[i] == '0') {
return 0;
}
//不要当前字符
int ans = process(i + 1, str);
//要当前字符
if (i + 1 < str.length && (str[i] - '0') * 10 + (str[i + 1] - '0') < 27) {
ans += process(i + 2, str);
}
return ans;
}
}
static class Dp1 {
public static int number(String s) {
if (s == null || s.length() == 0) {
return 0;
}
int n = s.length();
int[] dp = new int[n + 1];
dp[n] = 1;
char[] str = s.toCharArray();
for (int i = n - 1; i >= 0; i--) {
if (str[i] != '0') {
int ans = dp[i + 1];
if (i + 1 < str.length && (str[i] - '0') * 10 + (str[i + 1] - '0') < 27) {
ans += dp[i + 2];
}
dp[i] = ans;
}
}
return dp[0];
}
}
public static void main(String[] args){
int testTime = 10000;
System.out.println("start");
int maxStrLength = 100;
for (int i = 0; i < testTime; i++) {
int length = (int) (maxStrLength * Math.random());
String s = createRandomString(length);
int r = Recursion1.number(s);
int dp = Dp1.number(s);
if (r != dp) {
System.out.println("r = " + r);
System.out.println("dp = " + dp);
break;
}
}
System.out.println("end");
}
public static String createRandomString(int length) {
if (length == 0) {
return Math.random() < 0.5 ? null : "";
}
StringBuffer str = new StringBuffer();
for (int i = 0; i < length; i++) {
str.append((int)(Math.random() * 10));
}
return str.toString();
}
}

@ -1,10 +1,214 @@
package leo.class19;
import java.io.BufferedReader;
import java.util.function.IntPredicate;
/**
* @author Leo
* @ClassName Knapsack
* @DATE 2021/1/6 9:43
* @Description
* @Description
*
*/
public class Knapsack {
static class Recursion {
/**
* : ,
* @author Leo
* @date 2021/1/7 4:38
* @param w
* @param v
* @param bag
* @return int
*/
public static int maxValue(int[] w, int[] v, int bag) {
if (w == null || v == null || w.length != v.length || w.length == 0) {
return 0;
}
return process(w, v, 0, bag);
}
/**
* :
* @author Leo
* @date 2021/1/7 4:40
* @param w
* @param v
* @param i i
* @param bag
* @return int
*/
private static int process(int[] w, int[] v, int i, int bag) {
if (bag < 0) {
return -1;
}
if (i == w.length) {
return 0;
}
//不要当前的货
int p1 = process(w, v, i + 1, bag);
//要当前的货
int next = process(w, v, i + 1, bag - w[i]);
int p2 = 0;
//防止超出bag容量
if (next != -1) {
p2 = v[i] + next;
}
return Math.max(p1, p2);
}
}
static class RecursionDP {
public static int maxValue(int[] w, int[] v, int bag) {
if (w == null || v == null || w.length != v.length || w.length == 0) {
return 0;
}
int n = w.length;
int[][] dp = new int[n + 1][bag + 1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j <= bag; j++) {
dp[i][j] = -1;
}
}
int value = process(w, v, 0, bag, dp);
return value;
}
private static int process(int[] w, int[] v,int i, int bag, int[][] dp) {
if (bag < 0) {
return -3;
}
if (i == w.length) {
return 0;
}
if (dp[i][bag] != -1) {
return dp[i][bag];
}
int ans = 0;
int p1 = process(w, v, i + 1, bag, dp);
int next = process(w, v, i + 1, bag - w[i], dp);
int p2 = 0;
if (next != -3) {
p2 = v[i] + next;
}
ans = Math.max(p1, p2);
dp[i][bag] = ans;
return ans;
}
}
static class Dp {
public static int maxValue(int[] w, int[] v, int bag) {
if (w == null || v == null || w.length != v.length || w.length == 0) {
return 0;
}
int n = w.length;
int[][] dp = new int[n + 1][bag + 1];
for (int i = n - 1; i >= 0; i--) {
for (int rest = 0; rest <= bag; rest++) {
int p1 = dp[i + 1][rest];
int p2 = rest - w[i] < 0 ? -1 : v[i] + dp[i + 1][rest - w[i]];
dp[i][rest] = Math.max(p1, p2);
}
}
return dp[0][bag];
}
}
static class Recursion1 {
public static int maxValue(int[] w, int[] v, int bag) {
if (w == null || v == null || w.length != v.length || w.length == 0) {
return 0;
}
return process(w, v, 0, bag);
}
private static int process(int[] w, int[] v, int i, int rest) {
if (rest < 0) {
return -1;
}
if (i == w.length) {
return 0;
}
//不要当前货
int p1 = process(w, v, i + 1, rest);
//要当前货
int next = process(w, v, i + 1, rest - w[i]);
int p2 = 0;
if (next != -1) {
p2 = v[i] + next;
}
return Math.max(p1, p2);
}
}
static class Dp1 {
public static int maxValue(int[] w, int[] v, int bag) {
if (w == null || v == null || w.length != v.length || w.length == 0) {
return 0;
}
int n = w.length;
int[][] dp = new int[n + 1][bag + 1];
//int[n] dp == 0;
for (int i = n - 1; i >= 0; i--) {
for (int rest = 0; rest <= bag; rest++) {
int p1 = dp[i + 1][rest];
int p2 = rest - w[i] < 0 ? -1 : v[i] + dp[i + 1][rest - w[i]];
dp[i][rest] = Math.max(p1, p2);
}
}
return dp[0][bag];
}
}
public static void main(String[] args) {
int maxSize = 20;
int range = 30;
int maxBag = 30;
int testTime = 1000;
System.out.println("start");
for (int i = 0; i < testTime; i++) {
int size = (int) (maxSize * Math.random());
int bag = (int) (maxBag * Math.random());
int[] weights = createRandomArray(size, range);
int[] values = createRandomArray(size, range);
int r = Recursion1.maxValue(weights, values, bag);
int rDp = RecursionDP.maxValue(weights, values, bag);
int dp = Dp1.maxValue(weights, values, bag);
if (r != rDp || rDp != dp || r != dp) {
System.out.println("r = " + r);
System.out.println("rDp = " + rDp);
System.out.println("dp = " + dp);
break;
}
}
System.out.println("end");
}
public static int[] createRandomArray(int size, int range) {
if (size == 0) {
return null;
}
int[] arr = new int[size];
for (int i = 0; i < arr.length; i++) {
arr[i] = (int) (range * Math.random());
}
return arr;
}
}

@ -0,0 +1,97 @@
package leo.class19;
/**
* @author Leo
* @ClassName LongestCommonSubsequence
* @DATE 2021/1/8 1:57
* @Description
*
* ,
*
*  text1  text2
*   
* "ace" "abcde" "aec" "abcde"
* 0
*
* https://leetcode-cn.com/problems/longest-common-subsequence
*/
public class LongestCommonSubsequence {
static class Recursion {
public static int longestCommonSubsequence(String s1, String s2) {
if (s1 == null || s2 == null || s1.length() == 0 || s2.length() == 0) {
return 0;
}
char[] c1 = s1.toCharArray();
char[] c2 = s2.toCharArray();
//尝试
return process(c1, c2, c1.length - 1, c2.length - 1);
}
/**
* : c1[0...i]c2[0...j]
* @author Leo
* @date 2021/1/8 3:14
* @param c1
* @param c2
* @param i c1
* @param j c2
* @return int
*/
public static int process(char[] c1, char[] c2, int i, int j) {
if (i == 0 && j == 0) {
return c1[0] == c2[0] ? 1 : 0;
} else if (i == 0) {
if (c1[i] == c2[j]) {
return 1;
}else{
return process(c1, c2, i, j - 1);
}
} else if (j == 0) {
if (c1[i] == c2[j]) {
return 1;
}else {
return process(c1, c2, i - 1, j);
}
}else {
//i!=0&&j!=0
//可能考虑j
int p1 = process(c1, c2, i - 1, j);
//可能考虑i
int p2 = process(c1, c2, i, j - 1);
//如果两边相等,不考虑i和j
int p3 = c1[i] == c2[j] ? 1 + process(c1, c2, i - 1, j - 1) : 0;
return Math.max(p1, Math.max(p2, p3));
}
}
}
static class Dp {
public static int longestCommonSubsequence(String s1, String s2) {
if (s1 == null || s2 == null || s1.length() == 0 || s2.length() == 0) {
return 0;
}
char[] c1 = s1.toCharArray();
char[] c2 = s2.toCharArray();
int n = c1.length;
int m = c2.length;
int[][] dp = new int[n][m];
dp[0][0] = c1[0] == c2[0] ? 1 : 0;
for (int j = 1; j < c2.length; j++) {
dp[0][j] = c1[0] == c2[j] ? 1 : dp[0][j - 1];
}
for (int i = 1; i < c1.length; i++) {
dp[i][0] = c1[i] == c2[0] ? 1 : dp[i - 1][0];
}
for (int i = 1; i < n; i++) {
for (int j = 1; j < m; j++) {
int p1 = dp[i - 1][j];
int p2 = dp[i][j - 1];
int p3 = c1[i] == c2[j] ? 1 + dp[i - 1][j - 1] : 0;
dp[i][j] = Math.max(p1, Math.max(p2, p3));
}
}
return dp[n - 1][m - 1];
}
}
}

@ -1,10 +1,246 @@
package leo.class19;
import java.util.HashMap;
import java.util.Map;
/**
* @author Leo
* @ClassName StickersToSpellWord
* @DATE 2021/1/7 5:52
* @Description
* https://leetcode.com/problems/stickers-to-spell-word
* strarr
* arr使str
*
* str= "babac"arr = {"ba","c","abcd"}
* "ba""abcd"使2a2b1cstr2
*/
public class StickersToSpellWord {
static class Recursion {
public static int minStickers(String[] stickers, String target) {
if (stickers == null || stickers.length == 0) {
return -1;
}
int ans = process(stickers, target);
return ans == Integer.MAX_VALUE ? -1 : ans;
}
/**
* :
* @author Leo
* @date 2021/1/8 10:40
* @param stickers
* @param target
* @throw
* @return int
*/
private static int process(String[] stickers, String target) {
if (target.length() == 0) {
return 0;
}
int min = Integer.MAX_VALUE;
for (String sticker : stickers) {
String rest = minus(sticker, target);
//rest 剩余目标
//如果剩余目标长度不等于目标长度,代表匹配成功了,继续匹配剩余的目标
if (rest.length() != target.length()) {
//如果没有有效解,会返回MAX_VALUE
min = Math.min(min, process(stickers, rest));
}
}
return min + (min == Integer.MAX_VALUE ? 0 : 1);
}
private static String minus(String sticker, String target) {
char[] s = sticker.toCharArray();
char[] t = target.toCharArray();
int[] count = new int[26];
for (int i = 0; i < s.length; i++) {
count[s[i] - 'a']++;
}
for (int i = 0; i < t.length; i++) {
count[t[i] - 'a']--;
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < count.length; i++) {
if (count[i] > 0) {
for (int j = 0; j < count[i]; j++) {
sb.append((char) (i + 'a'));
}
}
}
return sb.toString();
}
}
static class DpZuo {
public static int minStickers(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 = process(counts, target);
return ans == Integer.MAX_VALUE ? -1 : ans;
}
// stickers[i] 数组当初i号贴纸的字符统计 int[][] stickers -> 所有的贴纸
// 每一种贴纸都有无穷张
// 返回搞定target的最少张数
// 最少张数
public static int process(int[][] stickers, String t) {
if (t.length() == 0) {
return 0;
}
// target做出词频统计
// target aabbc 2 2 1..
// 0 1 2..
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, process(stickers, rest));
}
}
return min + (min == Integer.MAX_VALUE ? 0 : 1);
}
}
static class Dp {
public static int minStickers(String[] stickers, String target) {
int n = stickers.length;
int[][] count = new int[n][26];
for (int i = 0; i < count.length; i++) {
char[] chars = stickers[i].toCharArray();
for (char c : chars) {
count[i][c - 'a']++;
}
}
HashMap<String, Integer> dp = new HashMap<>();
dp.put("", 0);
int ans = process(count, target,dp);
return ans == Integer.MAX_VALUE ? -1 : ans;
}
private static int process(int[][] stickers, String target, HashMap<String, Integer> dp) {
if (dp.containsKey(target)){
return dp.get(target);
}
if (target.length() == 0) {
return 0;
}
int min = Integer.MAX_VALUE;
//target词频统计
char[] t = target.toCharArray();
int[] tCount = new int[26];
for (char c : t) {
tCount[c - 'a']++;
}
for (int i = 0; i < stickers.length; i++) {
//第i号纸条
int[] sticker = stickers[i];
//通过target第一个字符比对,需要哪些贴纸(剪枝,贪心)
if (sticker[t[0] - 'a'] > 0) {
StringBuffer sb = new StringBuffer();
//开始判断需要的纸条,以及剩下的target
for (int j = 0; j < 26; j++) {
int num = tCount[j] - sticker[j];
for (int k = 0; k < num; k++) {
sb.append((char) (j + 'a'));
}
}
String restTarget = sb.toString();
min = Math.min(min, process(stickers, restTarget, dp));
}
}
int ans = min + (min == Integer.MAX_VALUE ? 0 : 1);
dp.put(target, ans);
return ans;
}
}
static class Dp1{
public static int minStickers(String[] stickers, String target) {
int n = stickers.length;
int[][] count = new int[n][26];
for (int i = 0; i < n; i++) {
char[] chars = stickers[i].toCharArray();
for (char c : chars) {
count[i][c - 'a']++;
}
}
Map<String, Integer> dp = new HashMap<>();
dp.put("", 0);
int ans = process(count, target, dp);
return ans == Integer.MAX_VALUE ? -1 : ans;
}
private static int process(int[][] stickers, String target, Map<String, Integer> dp) {
if (dp.containsKey(target)) {
return dp.get(target);
}
if (target.length() == 0) {
return 0;
}
char[] t = target.toCharArray();
//统计target词频
int[] tCount = new int[26];
for (char c : t) {
tCount[c - 'a']++;
}
int min = Integer.MAX_VALUE;
for (int i = 0; i < stickers.length; i++) {
int[] sticker = stickers[i];
if (sticker[t[0] - 'a'] > 0) {
StringBuffer sb = new StringBuffer();
for (int j = 0; j < 26; j++) {
int num = tCount[j] - sticker[j];
for (int k = 0; k < num; k++) {
sb.append((char) (j + 'a'));
}
}
String rest = sb.toString();
min = Math.min(min, process(stickers, rest, dp));
}
}
min += min == Integer.MAX_VALUE ? 0 : 1;
dp.put(target, min);
return min;
}
}
public static void main(String[] args){
String[] stickers = {"heavy", "claim", "seven", "set", "had", "it", "dead", "jump", "design", "question", "sugar", "dress", "any", "special", "ground", "huge", "use", "busy", "prove", "there", "lone", "window", "trip", "also", "hot", "choose", "tie", "several", "be", "that", "corn", "after", "excite", "insect", "cat", "cook", "glad", "like", "wont", "gray", "especially", "level", "when", "cover", "ocean", "try", "clean", "property", "root", "wing"};
String target = "travelbell";
System.out.println(Dp.minStickers(stickers, target));
System.out.println(Dp1.minStickers(stickers, target));
}
}

Loading…
Cancel
Save