从英文中重建数字

130 阅读1分钟

423. 从英文中重建数字 - 力扣(LeetCode)

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

示例 1:

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

示例 2:

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

提示:

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

思路

本题我们可以依次求每个数字出现的次数。先观察英文 0 到 9 的表示 zeroonetwothreefourfivesixseveneightnine,可以得出每个字母分别在那些数字中出现

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

我们遍历 s,统计出每个字母出现的次数,用 count(alpha) 表示字母 alphas 中出现的次数,用f(n) 表示数字的个数,再结合上表知

  • f(8) = count('g')
  • f(4) = count('u')
  • f(2) = count('w')
  • f(6) = count('x')
  • f(0) = count('z')
  • f(5) = count('f') - f(4)
  • f(3) = count('h') - f(8)
  • f(7) = count('s') - f(6)
  • f(9) = count('i') - f(5) - f(6) - f(8)
  • f(1) = count('n') - f(7) - f(9) * 2 // 因为nine中有两个n

解题

/**
 * @param {string} s
 * @return {string}
 */
var originalDigits = function (s) {
  const alphas = [
    "e",
    "g",
    "f",
    "i",
    "h",
    "o",
    "n",
    "s",
    "r",
    "u",
    "t",
    "w",
    "v",
    "x",
    "z",
  ];
  const map = new Map(alphas.map((a) => [a, 0]));
  for (let i = 0; i < s.length; i++) {
    let cnt = map.get(s[i]);
    map.set(s[i], cnt + 1);
  }
  const counts = Array(10).fill(0);
  counts[8] = map.get("g");
  counts[4] = map.get("u");
  counts[2] = map.get("w");
  counts[6] = map.get("x");
  counts[0] = map.get("z");
  counts[5] = map.get("f") - counts[4];
  counts[3] = map.get("h") - counts[8];
  counts[7] = map.get("s") - counts[6];
  counts[9] = map.get("i") - counts[5] - counts[6] - counts[8];
  counts[1] = map.get("n") - counts[7] - counts[9] * 2;
  return counts.map((c, i) => Array(c).fill(i).join("")).join("");
};