[LeetCode] Reconstruct Original Digits from English rebuild numbers from English-Alibaba Cloud Developer Community

Given a non-empty string containing an out-of-order English representation of digits 0-9, output the digits in ascending order.

Note:

1. Input contains only lowercase English letters.
2. Input is guaranteed to be valid and can be transformed to its original digits. That means invalid inputs such as "abc" or "zerone" are not permitted.
3. Input length is less than 50,000.

Example 1:

Input: "owoztneoer"
Output: "012"

Example 2:

Input: "fviefuro"
Output: "45"

this question gives us an English string, which is composed of English words representing numbers. However, the sequence of characters is confusing. Let's reconstruct numbers. Then the idea of this question is to count the number of occurrences of each character first, then calculate the number of occurrences of each word, and then reconstruct it. Because the input string must be valid in the title, the reconstruction cannot be successful. Here, we need to use a trick. We carefully observe these words that represent numbers: "zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", we can find that the characters of some words are unique, for example, z, only appears in zero, and w,u,x, the four words g only appear in two,four,six and eight respectively, then the number of these five numbers can be determined, because the word containing o has zero,two,four,one, the first three of which are confirmed, then the number of one will be known; Because there are eight,three words containing h, eight of which are known, then the number of three is known; Since there are four or five words containing f, and four of them are known, then the number of five is known; Because there are six words containing s, seven, where the number of six is known, then the number of seven is known; Because there are six,eight,five,nine words containing I, the first three of which are all determined, then the number of nine will be known, and it will be much easier if we know these problems. We will "zero", "two", "four", "six" in this order ", " eight ", " one ", " three ", " five ", " seven ", " nine "can find all the numbers. See the following code:

solution 1:

class Solution {
public:
string originalDigits(string s) {
string res = "";
vector<string> words{"zero", "two", "four", "six", "eight", "one", "three", "five", "seven", "nine"};
vector<int> nums{0, 2, 4, 6, 8, 1, 3, 5, 7, 9}, counts(26, 0);
vector<char> chars{'z', 'w', 'u', 'x', 'g', 'o', 'h', 'f', 's', 'i'};
for (char c : s) ++counts[c - 'a'];
for (int i = 0; i < 10; ++i) {
int cnt = counts[chars[i] - 'a'];
for (int j = 0; j < words[i].size(); ++j) {
counts[words[i][j] - 'a'] -= cnt;
}
while (cnt--) res += (nums[i] + '0');
}
sort(res.begin(), res.end());
return res;
}
};

in addition, we can also use a more concise and easy-to-understand method to quickly find the number of each number. For more information, see the following code:

solution 2:

class Solution {
public:
string originalDigits(string s) {
string res = "";
vector<int> counts(128, 0), nums(10, 0);
for (char c : s) ++counts[c];
nums = counts['z'];
nums = counts['w'];
nums = counts['u'];
nums = counts['x'];
nums = counts['g'];
nums = counts['o'] - nums - nums - nums;
nums = counts['h'] - nums;
nums = counts['f'] - nums;
nums = counts['s'] - nums;
nums = counts['i'] - nums - nums - nums;
for (int i = 0; i < nums.size(); ++i) {
for (int j = 0; j < nums[i]; ++j) {
res += (i + '0');
}
}
return res;
}
};