1
class Solution {
2

3
// First letter is unique after previous entries have been handled:
4
static final String[] UNIQUES =
5
new String[] {
6
"zero", "wto", "geiht", "xsi", "htree",
7
"seven", "rfou", "one", "vfie", "inne"
8
};
9

10
// Values corresponding to order of uniqueness checks:
11
static final int[] VALS = new int[] {0, 2, 8, 6, 3, 7, 4, 1, 5, 9};
12

13
// Maps for checking uniqueness more conveniently:
14
static final Map<Integer, List<Integer>> ORDERED_FREQ_MAP;
15
static final Map<Integer, Integer> ORDERED_DIGIT_MAP;
16

17
static {
18
// Initialize our ordered frequency map: 0-25 key to 0-25 values finishing the word:
19
final LinkedHashMap<Integer, List<Integer>> orderedFreqMap = new LinkedHashMap<>();
20
// Also initialize a digit lookup map, e.g. 'g' becomes 6 maps to 8 for ei[g]ht:
21
final LinkedHashMap<Integer, Integer> orderedDigitMap = new LinkedHashMap<>();
22
for (int i = 0; i < 10; ++i) {
23
final char unique = UNIQUES[i].charAt(0);
24
final int ui = convert(unique);
25
orderedFreqMap.put(ui, converting(UNIQUES[i].substring(1).toCharArray()));
26
orderedDigitMap.put(ui, VALS[i]);
27
}
28
// Let's make sure we aren't tempted to modify these since they're static.
29
ORDERED_FREQ_MAP = Collections.unmodifiableMap(orderedFreqMap);
30
ORDERED_DIGIT_MAP = Collections.unmodifiableMap(orderedDigitMap);
31
}
32

33
public String originalDigits(String s) {
34
// count frequencies of each letter in s:
35
final int[] freqs = new int[26];
36
for (int i = 0; i < s.length(); ++i) {
37
freqs[convert(s.charAt(i))]++;
38
}
39
// Crate an array to store digit strings in order, e.g. '00000', '11, '2222222', etc.
40
final String[] strings = new String[10];
41
// Iterate through uniqueness checks in order:
42
for (Map.Entry<Integer, List<Integer>> entry : ORDERED_FREQ_MAP.entrySet()) {
43
final int index = entry.getKey(); // unique letter in 0-25 form
44
final int value =
45
ORDERED_DIGIT_MAP.get(index); // corresponding digit, e.g. 8 for 'g', 0 for 'z', etc.
46
final int count =
47
freqs[index]; // frequency of unique letter = frequency of corresponding digit
48
if (count > 0) {
49
// update frequencies to remove the digit's word count times:
50
freqs[index] -= count;
51
for (int idx : entry.getValue()) {
52
freqs[idx] -= count;
53
}
54
// now create the digit string for the unique digit: the digit count times:
55
strings[value] = String.valueOf(value).repeat(count);
56
} else {
57
// count 0 - empty strring for this digit
58
strings[value] = "";
59
}
60
}
61
// append the digit strings in order
62
final StringBuilder sb = new StringBuilder();
63
for (String str : strings) {
64
sb.append(str);
65
}
66
// and we are done!
67
return sb.toString();
68
}
69

70
// Converts a character array into a list of 0-25 frequency values.
71
private static final List<Integer> converting(char... carr) {
72
final List<Integer> list = new ArrayList<>();
73
for (char ch : carr) {
74
list.add(convert(ch)); // converts each to 0-25
75
}
76
return Collections.unmodifiableList(list);
77
}
78

79
// Converts a-z to 0-26. Bitwise AND with 31 gives a=1, z=26, so then subtract one.
80
private static final Integer convert(char ch) {
81
return (ch & 0x1f) - 1; // a->0, z->25
82
}
83
}

0

WPM •0 •0

100%

ACC •0 •0

0s

TIME •0