modify code

pull/6/head
algorithmzuo 5 years ago
parent 1cd505fffa
commit e204c3f0d9

@ -3,6 +3,43 @@ package class46;
// 本题测试链接 : https://leetcode.com/problems/burst-balloons/
public class Code01_BurstBalloons {
public static int maxCoins0(int[] arr) {
// [3,2,1,3]
// [1,3,2,1,3,1]
int N = arr.length;
int[] help = new int[N + 2];
for (int i = 0; i < N; i++) {
help[i + 1] = arr[i];
}
help[0] = 1;
help[N + 1] = 1;
return func(help, 1, N);
}
// L-1位置和R+1位置永远不越界并且[L-1] 和 [R+1] 一定没爆呢!
// 返回arr[L...R]打爆所有气球,最大得分是什么
public static int func(int[] arr, int L, int R) {
if (L == R) {
return arr[L - 1] * arr[L] * arr[R + 1];
}
// 尝试每一种情况,最后打爆的气球,是什么位置
// L...R
// L位置的气球最后打爆
int max = func(arr, L + 1, R) + arr[L - 1] * arr[L] * arr[R + 1];
// R位置的气球最后打爆
max = Math.max(max, func(arr, L, R - 1) + arr[L - 1] * arr[R] * arr[R + 1]);
// 尝试所有L...R中间的位置(L,R)
for (int i = L + 1; i < R; i++) {
// i位置的气球最后打爆
int left = func(arr, L, i - 1);
int right = func(arr, i + 1, R);
int last = arr[L - 1] * arr[i] * arr[R + 1];
int cur = left + right + last;
max = Math.max(max, cur);
}
return max;
}
public static int maxCoins1(int[] arr) {
if (arr == null || arr.length == 0) {
return 0;

@ -3,6 +3,23 @@ package class46;
// 本题测试链接 : https://leetcode.com/problems/remove-boxes/
public class Code02_RemoveBoxes {
// arr[L...R]消除而且前面跟着K个arr[L]这个数
// 返回:所有东西都消掉,最大得分
public static int func1(int[] arr, int L, int R, int K) {
if (L > R) {
return 0;
}
int ans = func1(arr, L + 1, R, 0) + (K + 1) * (K + 1);
// 前面的K个X和arr[L]数合在一起了现在有K+1个arr[L]位置的数
for (int i = L + 1; i <= R; i++) {
if (arr[i] == arr[L]) {
ans = Math.max(ans, func1(arr, L + 1, i - 1, 0) + func1(arr, i, R, K + 1));
}
}
return ans;
}
public static int removeBoxes1(int[] boxes) {
int N = boxes.length;
int[][][] dp = new int[N][N][N];
@ -41,10 +58,15 @@ public class Code02_RemoveBoxes {
if (dp[L][R][K] > 0) {
return dp[L][R][K];
}
// 找到开头,
// 1,1,1,1,1,5
// 3 4 5 6 7 8
// !
int last = L;
while (last + 1 <= R && boxes[last + 1] == boxes[L]) {
last++;
}
// K个1 (K + last - L) last
int pre = K + last - L;
int ans = (pre + 1) * (pre + 1) + process2(boxes, last + 1, R, 0, dp);
for (int i = last + 2; i <= R; i++) {

@ -59,6 +59,9 @@ public class Code03_DeleteAdjacentSameCharacter {
return process(str, 0, str.length - 1, false);
}
// str[L...R] 前面有没有跟着[L]字符has T 有 F 无
// L,R,has
// 最少能剩多少字符,消不了
public static int process(char[] str, int L, int R, boolean has) {
if (L > R) {
return 0;
@ -72,6 +75,7 @@ public class Code03_DeleteAdjacentSameCharacter {
K++;
index++;
}
// index表示第一个不是[L]字符的位置
int way1 = (K > 1 ? 0 : 1) + process(str, index, R, false);
int way2 = Integer.MAX_VALUE;
for (int split = index; split <= R; split++) {

@ -0,0 +1,214 @@
package class46;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map.Entry;
import java.util.PriorityQueue;
// 本文件不牵扯任何byte类型的转化
// 怎么转byte自己来我只负责huffman算法本身的正确实现
// 字符串为空的时候,自己处理边界吧
// 实现的代码通过了大样本随机测试的对数器
// 可以从main函数的内容开始看起
public class HuffmanTree {
// 根据文章str, 生成词频统计表
public static HashMap<Character, Integer> countMap(String str) {
HashMap<Character, Integer> ans = new HashMap<>();
char[] s = str.toCharArray();
for (char cha : s) {
if (!ans.containsKey(cha)) {
ans.put(cha, 1);
} else {
ans.put(cha, ans.get(cha) + 1);
}
}
return ans;
}
public static class Node {
public int count;
public Node left;
public Node right;
public Node(int c) {
count = c;
}
}
public static class NodeComp implements Comparator<Node> {
@Override
public int compare(Node o1, Node o2) {
return o1.count - o2.count;
}
}
// 根据由文章生成词频表countMap生成哈夫曼编码表
// key : 字符
// value: 该字符编码后的二进制形式
// 比如,频率表 A60, B:45, C:13 D:69 E:14 F:5 G:3
// A 10
// B 01
// C 0011
// D 11
// E 000
// F 00101
// G 00100
public static HashMap<Character, String> huffmanForm(HashMap<Character, Integer> countMap) {
HashMap<Character, String> ans = new HashMap<>();
if (countMap.size() == 1) {
for (char key : countMap.keySet()) {
ans.put(key, "0");
}
return ans;
}
HashMap<Node, Character> nodes = new HashMap<>();
PriorityQueue<Node> heap = new PriorityQueue<>(new NodeComp());
for (Entry<Character, Integer> entry : countMap.entrySet()) {
Node cur = new Node(entry.getValue());
char cha = entry.getKey();
nodes.put(cur, cha);
heap.add(cur);
}
while (heap.size() != 1) {
Node a = heap.poll();
Node b = heap.poll();
Node h = new Node(a.count + b.count);
h.left = a;
h.right = b;
heap.add(h);
}
Node head = heap.poll();
fillForm(head, "", nodes, ans);
return ans;
}
public static void fillForm(Node head, String pre, HashMap<Node, Character> nodes, HashMap<Character, String> ans) {
if (nodes.containsKey(head)) {
ans.put(nodes.get(head), pre);
} else {
fillForm(head.left, pre + "0", nodes, ans);
fillForm(head.right, pre + "1", nodes, ans);
}
}
// 原始字符串str根据哈夫曼编码表转译成哈夫曼编码返回
public static String huffmanEncode(String str, HashMap<Character, String> huffmanForm) {
char[] s = str.toCharArray();
StringBuilder builder = new StringBuilder();
for (char cha : s) {
builder.append(huffmanForm.get(cha));
}
return builder.toString();
}
// 原始字符串的哈夫曼编码huffmanEncode根据哈夫曼编码表还原成原始字符串
public static String huffmanDecode(String huffmanEncode, HashMap<Character, String> huffmanForm) {
TrieNode root = createTrie(huffmanForm);
TrieNode cur = root;
char[] encode = huffmanEncode.toCharArray();
StringBuilder builder = new StringBuilder();
for (int i = 0; i < encode.length; i++) {
int index = encode[i] == '0' ? 0 : 1;
cur = cur.nexts[index];
if (cur.nexts[0] == null && cur.nexts[1] == null) {
builder.append(cur.value);
cur = root;
}
}
return builder.toString();
}
public static TrieNode createTrie(HashMap<Character, String> huffmanForm) {
TrieNode root = new TrieNode();
for (char key : huffmanForm.keySet()) {
char[] path = huffmanForm.get(key).toCharArray();
TrieNode cur = root;
for (int i = 0; i < path.length; i++) {
int index = path[i] == '0' ? 0 : 1;
if (cur.nexts[index] == null) {
cur.nexts[index] = new TrieNode();
}
cur = cur.nexts[index];
}
cur.value = key;
}
return root;
}
public static class TrieNode {
public char value;
public TrieNode[] nexts;
public TrieNode() {
value = 0;
nexts = new TrieNode[2];
}
}
// 为了测试
public static String randomNumberString(int len, int range) {
char[] str = new char[len];
for (int i = 0; i < len; i++) {
str[i] = (char) ((int) (Math.random() * range) + 'a');
}
return String.valueOf(str);
}
// 为了测试
public static void main(String[] args) {
// 根据词频表生成哈夫曼编码表
HashMap<Character, Integer> map = new HashMap<>();
map.put('A', 60);
map.put('B', 45);
map.put('C', 13);
map.put('D', 69);
map.put('E', 14);
map.put('F', 5);
map.put('G', 3);
HashMap<Character, String> huffmanForm = huffmanForm(map);
for (Entry<Character, String> entry : huffmanForm.entrySet()) {
System.out.println(entry.getKey() + " : " + entry.getValue());
}
System.out.println("====================");
// str是原始字符串
String str = "CBBBAABBACAABDDEFBA";
System.out.println(str);
// countMap是根据str建立的词频表
HashMap<Character, Integer> countMap = countMap(str);
// hf是根据countMap生成的哈夫曼编码表
HashMap<Character, String> hf = huffmanForm(countMap);
// huffmanEncode是原始字符串转译后的哈夫曼编码
String huffmanEncode = huffmanEncode(str, hf);
System.out.println(huffmanEncode);
// huffmanDecode是哈夫曼编码还原成的原始字符串
String huffmanDecode = huffmanDecode(huffmanEncode, hf);
System.out.println(huffmanDecode);
System.out.println("====================");
System.out.println("大样本随机测试开始");
// 字符串最大长度
int len = 500;
// 所含字符种类
int range = 26;
// 随机测试进行的次数
int testTime = 100000;
for (int i = 0; i < testTime; i++) {
int N = (int) (Math.random() * len) + 1;
String test = randomNumberString(N, range);
HashMap<Character, Integer> counts = countMap(test);
HashMap<Character, String> form = huffmanForm(counts);
String encode = huffmanEncode(test, form);
String decode = huffmanDecode(encode, form);
if (!test.equals(decode)) {
System.out.println(test);
System.out.println(encode);
System.out.println(decode);
System.out.println("出错了!");
}
}
System.out.println("大样本随机测试结束");
}
}
Loading…
Cancel
Save