LeetCode探索(69):423-从英文中重建数字

188 阅读2分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第26天,点击查看活动详情

题目

给你一个字符串 s ,其中包含字母顺序打乱的用英文单词表示的若干数字(0-9)。按 升序 返回原始的数字。

示例 1:

输入:s = "owoztneoer"
输出:"012"

示例 2:

输入:s = "fviefuro"
输出:"45"

提示:

  • 1 <= s.length <= 105
  • s[i]["e","g","f","i","h","o","n","s","r","u","t","w","v","x","z"] 这些字符之一
  • s 保证是一个符合题目要求的字符串

思考

本题难度中等。

首先,我们要读懂题意。给出一个字符串s,返回一个数字组成的字符串,比如"45"对应英文字符"fourfive"随机化后的结果。题目是要我们反过来给出字符串s对应的数字字符串。

我们可以统计每个字母分别在哪些数字中出现:

字母数字
e0135789
f45
g8
h38
i5689
n179
o0124
r034
s67
t238
u4
v57
w2
x6
z0

我们不难发现,字母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 中出现的英文字母。

参考