题目描述
我叫王大锤,是一家出版社的编辑。我负责校对投稿来的英文稿件,这份工作非常烦人,因为每天都要去修正无数的拼写错误。但是,优秀的人总能在平凡的工作中发现真理。
我发现一个发现拼写错误的捷径:
1.三个同样的字母连在一起,一定是拼写错误,去掉一个的就好啦:比如 helllo -> hello
2.两对一样的字母(AABB型)连在一起,一定是拼写错误,去掉第二对的一个字母就好啦:比如 helloo -> hello
3.上面的规则优先“从左到右”匹配,即如果是AABBCC,虽然AABB和BBCC都是错误拼写,应该优先考虑修复AABB,结果为AABCC
请听题:请实现大锤的自动校对程序
注:题目删除了部分赘述,包括输入输出等,仅保留最终需要我们实现的部分
示例
输入:wooooooow输出:woow
思路
首先题目要求很明确,给你一个字符串,按照规则对字符串进行修改,规则也很明确,AAA型,AABB型属于有误字符串,去掉最后一个字符之后就能成为正常字符串。我们可以看到,需要进行校验的字符串,有明显的区间范围,即3个或者4个时候,我们才需要判断它是否合规,是否需要矫正,所以能够很容易的想到滑动窗口,每次对窗口中的字符进行校验,窗口前面的字符表示确认合规,窗口之中的字符表示正在校验,窗口之后的字符表示待验证。
接下来我们分析一下怎么进行窗口滑动,从做到右遍历元素
1.当窗口内仅有一个元素时,此时我们判断当前元素是否等于窗口内元素
等于,则当前元素与窗口内元素结合可能出现AAA型或者AABB型,需要将当前元素加入窗口中,继续往后遍历;
不等于,则窗口内元素可以判定为通过校验,从窗口中移除,并且计入最终字符串中,然后将当前元素放入窗口中,进行下一次的校验。
2.当窗口中存在两个元素,并且依据1的操作逻辑,这两个元素一定相等。此时我们判断当前元素是否等于窗口内元素
等于,则当前元素与窗口内元素结合成为AAA型,不符合规则,直接将当前元素丢弃,继续往后遍历
不等于,当前元素与窗口内元素结合可能成为AABB型,所以将当前元素放入窗口中,进行下一次的判断
3.当窗口中存在3个及以上元素时(最多只会3个),依据1,2的逻辑,此时窗口中存在的元素应该为AAB型,我们需要判断当前元素是否等于窗口中B型的元素
等于,则当前元素与窗口中元素结合成为AABB型,不符合规则,直接丢弃当前元素,继续往后遍历
不等于,则窗口中元素通过校验,直接从窗口中移除,并且计入最终字符串中,然后将当前元素放入窗口中,进行下一次校验
实现
public String repairSpell(String words) {
//最终字符串
StringBuilder answer = new StringBuilder();
//记录窗口内元素
StringBuilder temp = new StringBuilder();
temp.append(words.charAt(0));
for (int i = 1 ; i < words.length() ; i++) {
if (temp.length() == 1) {
if (words.charAt(i) == temp.charAt(0)) {
temp.append(words.charAt(i));
} else {
answer.append(temp);
temp.setLength(0);
temp.append(words.charAt(i));
}
continue;
}
if (temp.length() == 2) {
if (words.charAt(i) == temp.charAt(0)) {
continue;
}
temp.append(words.charAt(i));
}
if (temp.length() >= 3) {
if (words.charAt(i) == temp.charAt(temp.length() - 1)) {
continue;
}
answer.append(temp);
temp.setLength(0);
temp.append(words.charAt(i));
}
}
answer.append(temp);
return answer.toString();
}
附录
github上可以直接查看源代码以及测试用例:https://github.com/Carol0/Data-Structures-and-Algorithms/blob/main/dsa/src/main/java/com/carol/interview/bytedance/RepairSpell.java
B站上可以查看直播录制讲解视频:BV1Sg411H77Y