1. 题目来源
链接:长按键入
来源:LeetCode
2. 题目说明
你的朋友正在使用键盘输入他的名字 name。偶尔,在键入字符 c 时,按键可能会被长按,而字符可能被输入 1 次或多次。
你将会检查键盘输入的字符 typed。如果它对应的可能是你的朋友的名字(其中一些字符可能被长按),那么就返回 True。
说明:
初始化 nums1 和 nums2 的元素数量分别为 m 和 n。
你可以假设 nums1 有足够的空间(空间大小大于或等于 m + n)来保存 nums2 中的元素。
示例1:
输入:name = “alex”, typed = “aaleex”
输出:true
解释:‘alex’ 中的 ‘a’ 和 ‘e’ 被长按。
示例2:
输入:name = “saeed”, typed = “ssaaedd”
输出:false
解释:‘e’ 一定需要被键入两次,但在 typed 的输出中不是这样。
示例3:
输入:name = “leelee”, typed = “lleeelee”
输出:true
示例4:
输入:name = “laiden”, typed = “laiden”
输出:true
解释:长按名字中的字符并不是必要的。
提示:
- name.length <= 1000
- typed.length <= 1000
- name 和 typed 的字符都是小写字母。
3. 题目解析
遍历name:
- 如果name中含有n个连续重复字母,双指针均向后移n位。
- 如果typed与name的当前字母相同,仅将typed指针向后移位,判断是否为该字母的长按情况。
- 在对name的一个字母进行遍历的时候,typed指针位置一定会发生改变,若没发生改变,则该位置字母不匹配name,故直接返回false,在此采用flag进行记录判断。
- 需要注意的是flag位置不能在情况1之前,应当在情况1、2中间,若样例为name = “saeed”,flag = "ssaaedd"会发生调用两次情况1的while,修改了j的大小,导致输出true。
这个写法简单易理解,但是坑太多,也是代码质量不行,也许在特殊的样例情况下仍然通不过,但在LeetCode上都能够提交成功了…无奈。
同理有遍历typed的双指针写法,感觉比遍历name的方法要好很多
遍历typed:
- 判断当前typed与当前name是否相同
- 如1不成立,判断与前一个name字符是否相同
- 如若2不成立返回false
由于两个string的有效字符长度会不同,需要判断
4. 代码展示
遍历name代码展示:
class Solution {
public:
bool isLongPressedName(string name, string typed) {
for (int i = 0, j = 0; i < name.length(); ++i) {
while (name[i] == name[i + 1]) {
++i;
++j;
}
int flag = j;
while (typed[j] == name[i]) {
++j;
}
if (flag == j) return false;
}
return true;
}
};
以上代码遇到name = “aaall” typed = “daalll” 类似于这样的样例,name的重复元素会将typed覆盖掉连续的一部分。修改如下:
class Solution {
public:
bool isLongPressedName(string name, string typed) {
for (int i = 0, j = 0; i < name.length(); ++i) {
while ((name[i] == name[i + 1]) && (name[i] == typed[j])) {
++i;
++j;
}
int flag = j;
while (typed[j] == name[i]) {
++j;
}
if (flag == j) return false;
}
return true;
}
};
该flag位置必须在两while之间,若flag放置最前方,当name = “saeed”,flag = "ssaaedd"会发生调用两次情况1的while,修改了j的大小,导致输出true。
遍历typed代码展示:
bool isLongPressedName(string name, string typed) {
int j = 0, len = name.size();
for (int i = 0; i < typed.size(); i++) {
if (typed[i] == name[j] && j < len) {
j++;
continue;
}
else if (j > 0 && typed[i] == name[j - 1]) //首字母不同时j-1超出索引范围
continue;
else
return false;
}
if (j == len)
return true;
else
return false;
}