鹅厂员工爆料:团队来了个“技术活跃分子”,GitHub上每天都在打卡,周末忙着写博客,微信群里讨论得热火朝天。
看着他那么“拼”,还以为他就是那个技术大神,什么都能答得出来,知识点都是背得滚瓜烂熟的。
可是,正当大家讨论React性能优化的时候,大家的期望值瞬间崩塌——这位新人居然说:“这个问题我在博客里写过,但具体怎么解决...我得再查查资料。” 🤦♂️
说实话,我当时差点笑出声。你在博客里写过,但忘得比我还快,真的是...
但是先不要质疑,因为这种情况真的太常见了。我们程序员,特别是做技术的,怎么可能记住所有的细节呢?你看,技术更新速度快,项目多,时间紧,哪能把每个技术点都牢牢记住?
反正,别太纠结于记不住的细节,重要的是持续学习和解决问题的能力。
算法题:从英文中重建数字
聊一个看起来简单,但实际上能让不少人“抓狂”的算法题:从英文中重建数字。
题目给的场景是这样的:你有一段英文字符串,里面包含了数字的英文拼写。任务是从中恢复出数字。比如,“onezero”应该恢复成数字“10”,“twofour”应该变成“24”。
这听起来似乎没什么问题,对吧?直接去把“one”、“zero”拼接起来,不就能得到数字10了?但问题是,字母们是交织在一起的!比如在“onezero”里,“o”在“one”和“zero”中都出现过。我们得怎么确定这些字母究竟属于哪个数字呢?
别急,这里有个关键的地方——我们可以利用数字英文拼写中独特的字母来破解这些谜团。例如,“zero”是唯一一个包含字母‘z’的数字,“one”包含字母‘n’,而其他数字的拼写并不会包含这个字母。
第一步,思考数字和字母的关系
首先,我们需要理解不同数字的英文拼写中,哪些字母是独一无二的。例如:
‘z’只出现在“zero”中。 ‘w’只出现在“two”中。 ‘u’只出现在“four”中。 ‘x’只出现在“six”中。
这些字母就是我们的“提示符”。通过这些独特的字母,我们可以从英文中先提取出这些数字,然后去掉相应的字母,继续用同样的方法处理剩下的部分。
第二步,构建一个解法
具体的解决方法可以参考以下步骤:
遍历数字,从中提取出包含独特字母的数字。 在字符串中找到这些字母,移除它们。 重复这个过程,直到所有数字都被提取出来。
Java实现
下面是一个用Java实现的示例代码,简单明了:
import java.util.*;
public class ReconstructDigits {
public static String originalDigits(String s) {
// 数字字符的英文拼写映射
String[] digits = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine"};
// 结果计数
int[] count = new int[10];
// 字符串中各个字母出现的次数
int[] freq = new int[26];
// 统计输入字符串中每个字母的出现次数
for (char c : s.toCharArray()) {
freq[c - 'a']++;
}
// 用已知的独特字母来找到对应的数字
// 先处理 "zero", "two", "four", "six", "eight"
count[0] = freq['z' - 'a']; // zero
count[2] = freq['w' - 'a']; // two
count[4] = freq['u' - 'a']; // four
count[6] = freq['x' - 'a']; // six
count[8] = freq['g' - 'a']; // eight
// 然后处理剩下的数字
count[3] = freq['h' - 'a'] - count[8]; // three (包含 h, 但与 eight 重叠)
count[5] = freq['f' - 'a'] - count[4]; // five (包含 f, 但与 four 重叠)
count[7] = freq['s' - 'a'] - count[6]; // seven (包含 s, 但与 six 重叠)
count[1] = freq['o' - 'a'] - count[0] - count[2] - count[4]; // one
count[9] = freq['i' - 'a'] - count[5] - count[6] - count[8]; // nine (包含 i, 但与 five, six, eight 重叠)
// 拼接结果
StringBuilder result = new StringBuilder();
for (int i = 0; i < 10; i++) {
for (int j = 0; j < count[i]; j++) {
result.append(i);
}
}
return result.toString();
}
public static void main(String[] args) {
String input = "owoztneoer";
System.out.println(originalDigits(input)); // 输出 "012"
}
}
分析
字符统计:首先统计输入字符串中每个字母的出现次数。我们可以借助一个频率数组来做这件事,
freq[c - 'a']
就表示字母c
在字符串中的出现次数。独特字母判断:利用数字拼写中的独特字母,我们可以依次处理每个数字。例如,‘z’是“zero”中独有的字母,因此我们首先确定有多少个“zero”。
更新频率:在找到某个数字后,我们需要更新频率数组,移除已被提取的字母。
输出结果:最后,按照我们提取出的数字次数拼接结果,得到从英文中重建的数字。
结论
这道题考察了我们对字母和数字之间的关系的理解。我们并不需要在字符串中暴力地查找每个数字,而是通过巧妙利用字母的独特性,大大降低了问题的复杂度。最重要的是,通过这种方法,题目得以在时间复杂度上实现优化,避免了无意义的重复计算。
-END-
以上,就是今天的分享了,看完文章记得右下角给何老师点赞,也欢迎在评论区写下你的留言。