LeetCode 423. Reconstruct Original Digits from English 解题报告
题目描述
Given a non-empty string containing an out-of-order English representation of digits 0-9, output the digits in ascending order.
- Input contains only lowercase English letters.
- 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.
- Input length is less than 50,000.
示例
Example 1:
Input: “owoztneoer”
Output: “012”
Example 2:
Input: “fviefuro”
Output: “45”
限制条件
没有明确给出.
解题思路
我的思路:
这道题看起来就不是很难,第一步肯定得写一下各个数字对应的英文单词,看看它们都包含了哪些字符,并且找找有没有什么规律或是特点。
所以我列出了下面的表格:
字母 | 包含该字母的单词 |
---|---|
e | zero, one, three, five, seven, eight, nine |
f | four, five |
g | eight |
h | three, eight |
i | five, six, eight, nine |
n | one, seven, nine |
o | zero, one, two, four |
r | zero, three, four |
s | six, seven |
t | two, three, eight |
u | four |
v | five, seven |
w | two |
x | six |
z | zero |
由上表我们发现部分字符是某个单词独有,这意味着这些字符的个数就是数字的个数,比如说‘z’这个字符是zero单词独有的, 所以‘z’的个数就是0的个数。
如果我们用numbers数组存储出现的数字个数,其中下标表示着对应0-9的数字,那么我们会有下面这个结果:
数字 | 数字的个数 |
---|---|
0 | numbers[0] = ‘z’的个数 |
2 | numbers[2] = ‘w’的个数 |
4 | numbers[4] = ‘u’的个数 |
6 | numbers[6] = ‘x’的个数 |
8 | numbers[8] = ‘g’的个数 |
而其他的数字个数,比如5的个数,因为‘f’的数目由four和five的数目组成,而我们已知four的数目为numbers[4],所以numbers[5] = ‘f’的个数-number[4]。其他的数字同样处理。
最后我们得到了下面的结果:
数字 | 数字的个数 |
---|---|
0 | numbers[0] = ‘z’的个数 |
2 | numbers[2] = ‘w’的个数 |
4 | numbers[4] = ‘u’的个数 |
6 | numbers[6] = ‘x’的个数 |
8 | numbers[8] = ‘g’的个数 |
5 | numbers[5] = ‘f’的个数 - numbers[4] |
3 | numbers[3] = ‘h’的个数 - numbers[8] |
7 | numbers[7] = ‘s’的个数 - numbers[6] |
1 | numbers[1] = ‘o’的个数 - numbers[0] - numbers[2] - numbers[4] |
9 | numbers[9] = ‘i’的个数 - numbers[5] - numbers[6] - numbers[8] |
利用这个表格,通过代码找出上面表格中出现的字符的数目,然后按照表格里的公式,就能得到所有数字出现的次数,最后按照顺序把相应个数的数字添加到结果字符串中就通过了这道题。
Discuss中大牛们的解法核心思想都是找到字符数目与数字数目之间的联系,所以我跟他们的实现方法大同小异,下面贴出了我的两种实现方式,第一种方式很直观地重现了上述的过程,第二种方式用了count函数直接找表格中的字符数目。
代码
我的代码1
class Solution {
public:
string originalDigits(string s) {
map<char, int> letters;
vector<int> numbers(10, 0);
string res;
for (char c: s)
letters[c]++;
numbers[8] = letters['g'];
numbers[6] = letters['x'];
numbers[4] = letters['u'];
numbers[2] = letters['w'];
numbers[0] = letters['z'];
numbers[5] = letters['f'] - numbers[4];
numbers[3] = letters['h'] - numbers[8];
numbers[7] = letters['s'] - numbers[6];
numbers[1] = letters['o'] - numbers[0] - numbers[2] - numbers[4];
numbers[9] = letters['i'] - numbers[5] - numbers[6] - numbers[8];
for (int i = 0; i < 10; i++) {
while(numbers[i] > 0) {
res += ('0' + i);
numbers[i]--;
}
}
return res;
}
};
我的代码2
class Solution {
public:
string originalDigits(string s) {
map<char, int> myMap{
{'g', 8}, {'x', 6}, {'u', 4}, {'w', 2}, {'z', 0},
{'f', 5}, {'h', 3}, {'s', 7}, {'o', 1}, {'i', 9}
};
vector<int> numbers(10, 0);
string res;
for (auto p: myMap) {
numbers[p.second] = count(s.begin(), s.end(), p.first);
}
numbers[5] -= numbers[4];
numbers[3] -= numbers[8];
numbers[7] -= numbers[6];
numbers[1] -= (numbers[0] + numbers[2] + numbers[4]);
numbers[9] -= (numbers[5] + numbers[6] + numbers[8]);
for (int i = 0; i < 10; i++) {
while(numbers[i] > 0) {
res += ('0' + i);
numbers[i]--;
}
}
return res;
}
};
总结
这道题挺简单的,找找字符跟数字之间的数目关系就能做出来了,算是复习了一下map的用法吧。
轻松地填了这个坑,明天去干掉下一道似乎很难的题目,要加油了~