返回
前端笔试题的独特解法:深入剖析巧妙思路
前端
2024-01-07 11:51:51
前端笔试中,一道考察我们基本功和临场发挥能力的题目引起了我的兴趣,原作者给出了一个颇为巧妙的解法,着实令人赞叹。而今,在拥有充裕思考时间的前提下,本文将尝试从多个角度对这道题进行深入剖析,以期从中汲取更丰富的知识和经验。
首先,我们来看看这道题目:
题目:
给定一个字符串,要求将其中所有连续出现的重复字符压缩为单个字符。
示例:
- 输入:"aabbbcccaaa"
- 输出:"abca"
这道题看似简单,但要临场发挥出如此巧妙的解法绝非易事。原作者的解法如下:
function compressString(s) {
let compressed = "";
let count = 1;
for (let i = 0; i < s.length; i++) {
if (s[i] === s[i + 1]) count++;
else {
compressed += s[i] + count.toString();
count = 1;
}
}
return compressed.length < s.length ? compressed : s;
}
这个解法巧妙地利用了 JavaScript 字符串连接的特性,将字符和计数拼接在一起。通过遍历字符串,并在遇到连续重复字符时累加计数,最终得到压缩后的字符串。
为了进一步理解这个解法,我们不妨来手动模拟一下压缩过程:
- 遍历字符串 "aabbbcccaaa",遇到第一个字符 'a',计数为 1。
- 遇到第二个 'a',计数加 1,变为 2。
- 遇到第三个 'a',计数再加 1,变为 3。
- 此时遇到不同的字符 'b',将 'a' 和计数 '3' 拼接,得到 "a3"。
- 重置计数为 1,继续遍历,依次压缩 "b"、"c" 等字符。
- 最终得到压缩后的字符串 "a3b1c3a3"。
通过这个模拟过程,我们可以看到解法的核心在于字符和计数的拼接,以及在遇到不同字符时及时重置计数。这种思路不仅巧妙,而且在代码实现上也简洁易懂。
除了原作者给出的解法,本文还尝试探索其他可能的解法。例如,我们可以使用正则表达式来匹配连续重复的字符,然后用替换操作进行压缩:
function compressString(s) {
let compressed = s.replace(/(\w)\1+/g, "$1$+{count.length}");
return compressed.length < s.length ? compressed : s;
}
这个解法利用了正则表达式中的贪婪匹配,可以一次性匹配所有连续重复的字符。不过,需要注意的是,这个解法在某些情况下可能无法正确压缩字符串,例如当计数超过 9 时。
此外,我们还可以使用栈数据结构来实现压缩:
function compressString(s) {
let stack = [];
for (let i = 0; i < s.length; i++) {
if (stack.length > 0 && stack[stack.length - 1].char === s[i]) {
stack[stack.length - 1].count++;
} else {
stack.push({ char: s[i], count: 1 });
}
}
let compressed = "";
while (stack.length > 0) {
compressed += stack.pop().char + stack.pop().count.toString();
}
return compressed;
}
这个解法使用栈来记录连续重复的字符及其计数,最终通过出栈操作将压缩后的字符串拼接起来。这个解法的优势在于代码逻辑清晰,而且可以正确处理计数超过 9 的情况。
通过对这道笔试题的深入剖析,我们不仅学习了原作者巧妙的解法,还探索了其他可行的解法。在面试准备和技术提升的过程中,这种多角度思考和实践探索的方式无疑是极有价值的。