一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情。
题目
给你一个字符串 s ,其中包含字母顺序打乱的用英文单词表示的若干数字(0-9)。按 升序 返回原始的数字。
示例 1:
输入:s = "owoztneoer"
输出:"012"
示例 2:
输入:s = "fviefuro"
输出:"45"
提示:
1 <= s.length <= 105s[i]为["e","g","f","i","h","o","n","s","r","u","t","w","v","x","z"]这些字符之一s保证是一个符合题目要求的字符串
思考
本题难度中等。
首先,我们要读懂题意。给出一个字符串s,返回一个数字组成的字符串,比如"45"对应英文字符"fourfive"随机化后的结果。题目是要我们反过来给出字符串s对应的数字字符串。
我们可以统计每个字母分别在哪些数字中出现:
| 字母 | 数字 |
|---|---|
| e | 0135789 |
| f | 45 |
| g | 8 |
| h | 38 |
| i | 5689 |
| n | 179 |
| o | 0124 |
| r | 034 |
| s | 67 |
| t | 238 |
| u | 4 |
| v | 57 |
| w | 2 |
| x | 6 |
| z | 0 |
我们不难发现,字母z, w, u, x, g都只对应了一个数字,那么他们出现的次数,即分别为 0, 2, 4, 6, 8 出现的次数。
接下来,再计算其他数字出现的次数。
最后,按照升序进行字符串拼接,我们要根据数字的统计次数将数字拼接几次,最后得到字符串并返回。
解答
方法一:脑筋急转弯
/**
* @param {string} s
* @return {string}
*/
var originalDigits = function(s) {
// 统计每个字母出现的次数
const map = new Map()
for (let ch of s) {
map.set(ch, (map.get(ch) || 0) + 1)
}
// 计算数字出现的次数
const cnt = []
cnt[0] = map.get('z') || 0
cnt[2] = map.get('w') || 0
cnt[4] = map.get('u') || 0
cnt[6] = map.get('x') || 0
cnt[8] = map.get('g') || 0
cnt[3] = (map.get('h') || 0) - cnt[8]
cnt[5] = (map.get('f') || 0) - cnt[4]
cnt[7] = (map.get('s') || 0) - cnt[6]
cnt[1] = (map.get('o') || 0) - cnt[0] - cnt[2] - cnt[4]
cnt[9] = (map.get('i') || 0) - cnt[5] - cnt[6] - cnt[8]
// 按照升序进行拼接
let ans = ''
for (let i = 0; i < 10; ++i) { // 遍历数字0~9
for (let j = 0; j < cnt[i]; ++j) { // 根据数字的统计次数添加数字
ans += `${i}`
}
}
return ans
}
// 执行用时:88 ms, 在所有 JavaScript 提交中击败了68.29%的用户
// 内存消耗:45.5 MB, 在所有 JavaScript 提交中击败了53.66%的用户
// 通过测试用例:24 / 24
复杂度分析:
- 时间复杂度:
O(|s|),其中 |s| 是字符串 s 的长度。 - 空间复杂度:
O(|Σ|),其中 Σ 表示字符集,|Σ| 表示字符集的大小,在本题中 Σ 为所有在 0∼9 中出现的英文字母。