423. Reconstruct Original Digits from English

Backtrack(TLE)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
class Solution {
private static final String[] NUMS = new String[]{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};

public String originalDigits(String s) {
int[] countMap = new int[26];
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
countMap[c - 'a']++;
}

StringBuilder sb = new StringBuilder();
backtrack(sb, countMap, 0, s.length());
return sb.toString();
}

private boolean backtrack(StringBuilder sb, int[] countMap, int length, int targetLength) {
if (length == targetLength) {
return true;
}

for (int i = 0; i < NUMS.length; i++) {
String num = NUMS[i];
if (tryUseNum(countMap, num)) {
sb.append(i);
if (backtrack(sb, countMap, length + num.length(), targetLength)) {
return true;
}
revertNum(countMap, num);
sb.deleteCharAt(sb.length() - 1);
}
}

return false;
}

private boolean tryUseNum(int[] countMap, String num) {
boolean revert = false;
for (int i = 0; i < num.length(); i++) {
char c = num.charAt(i);
if (countMap[c - 'a']-- == 0) {
revert = true;
}
}

if (revert) {
revertNum(countMap, num);
return false;
} else {
return true;
}
}

private void revertNum(int[] countMap, String num) {
for (int i = 0; i < num.length(); i++) {
char c = num.charAt(i);
countMap[c - 'a']++;
}
}
}

Greedy

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
class Solution {
private static final String[] NUMS = new String[]{"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
private static final int[] PRIORITYS = new int[]{0, 2, 6, 8, 7, 4, 5, 3, 9, 1};
// private static final int[] PRIORITYS = new int[]{0, 8, 2, 6, 7, 5, 9, 4, 3, 1};
// private static final int[] PRIORITYS = new int[]{0, 8, 6, 3, 2, 7, 5, 9, 4, 1};

public String originalDigits(String s) {
int[] countMap = new int[26];
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
countMap[c - 'a']++;
}

StringBuilder sb = new StringBuilder();
for (int priority : PRIORITYS) {
String num = NUMS[priority];
int k = Integer.MAX_VALUE; // 最大抵消次数取决于最少的字符数
for (int j = 0; j < num.length(); j++) {
char c = num.charAt(j);
k = Math.min(k, countMap[c - 'a']);
}
for (int j = 0; j < num.length(); j++) {
char c = num.charAt(j);
countMap[c - 'a'] -= k;
}
while (k > 0) {
sb.append(priority);
k--;
}
}

char[] chars = sb.toString().toCharArray();
Arrays.sort(chars);
return new String(chars);
}

private boolean backtrack(StringBuilder sb, int[] countMap, int length, int targetLength) {
if (length == targetLength) {
return true;
}

for (int i = 0; i < NUMS.length; i++) {
String num = NUMS[i];
if (tryUseNum(countMap, num)) {
sb.append(i);
if (backtrack(sb, countMap, length + num.length(), targetLength)) {
return true;
}
revertNum(countMap, num);
sb.deleteCharAt(sb.length() - 1);
}
}

return false;
}

private boolean tryUseNum(int[] countMap, String num) {
boolean revert = false;
for (int i = 0; i < num.length(); i++) {
char c = num.charAt(i);
if (countMap[c - 'a']-- == 0) {
revert = true;
}
}

if (revert) {
revertNum(countMap, num);
return false;
} else {
return true;
}
}

private void revertNum(int[] countMap, String num) {
for (int i = 0; i < num.length(); i++) {
char c = num.charAt(i);
countMap[c - 'a']++;
}
}
}

References

423. Reconstruct Original Digits from English