925. Long Pressed Name*
https://leetcode.com/problems/long-pressed-name/
题目描述
Your friend is typing his name into a keyboard. Sometimes, when typing a character c, the key might get long pressed, and the character will be typed 1 or more times.
You examine the typed characters of the keyboard. Return True if it is possible that it was your friends name, with some characters (possibly none) being long pressed.
Example 1:
Input: name = "alex", typed = "aaleex"
Output: true
Explanation: 'a' and 'e' in 'alex' were long pressed.
Example 2:
Input: name = "saeed", typed = "ssaaedd"
Output: false
Explanation: 'e' must have been pressed twice, but it wasn't in the typed output.
Example 3:
Input: name = "leelee", typed = "lleeelee"
Output: true
Example 4:
Input: name = "laiden", typed = "laiden"
Output: true
Explanation: It's not necessary to long press any character.
Note:
-
name.length <= 1000 -
typed.length <= 1000 - The characters of
name andtyped are lowercase letters.
C++ 实现 1
本题先介绍讨论区的一种方法, 写法看起来简洁, 但是我感觉, 如果让我再一次写这道题, 我可能仍无法写成下面的样子. 之后的 C++ 实现 2 以及 C++ 实现 3 介绍按我的思路所实现的代码.
下面代码来自: [C++/Java/Python] Two Pointers, 使用双指针.
思路可以概括为: 如果 name[i] == typed[j], 那么指针 i 和 j 同时向后移动. 否则, 如果 j == 0 或者 typed[j] != typed[j - 1] 时, 直接返回 false, 这说明当前字符不是 long pressed 的. 但如果 typed[j] == typed[j - 1], 那么移动指针 j.
class Solution {
public:
bool isLongPressedName(string name, string typed) {
int i = 0, m = name.length(), n = typed.length();
for (int j = 0; j < n; ++j)
if (i < m && name[i] == typed[j])
++i;
else if (!j || typed[j] != typed[j - 1])
return false;
return i == m;
}
};
C++ 实现 2
我的实现, beats 100%. 思路也是双指针, 但基于如下考虑:
-
name 的长度肯定小于或等于typed 的长度, long pressed 的字符串肯定更长; - 对
name 和typed 遍历, 如果name[i] == typed[j], 那么两个指针同时向右移动. - 如果
name[i] != typed[j], 那么由于typed 是 long pressed 的字符, 如果type[j] == type[j - 1], 就要一直向右移动j, 找到第一个使typed[j] != typed[j - 1] 的j, 再判断此时typed[j] 是否等于name[i], 如果相等, 那么i 和j 仍要继续移动.
class Solution {
public:
bool isLongPressedName(string name, string typed) {
if (name.size() > typed.size()) return false;
int j = 0;
for (int i = 0; i < name.size(); ++ i) {
if (name[i] != typed[j]) {
while (j - 1 >= 0 && typed[j - 1] == typed[j]) ++ j;
if (typed[j] != name[i]) return false;
}
++ j;
}
return true;
}
};
C++ 实现 3
不想解析了, 思路反正很暴力.
class Solution {
public:
bool isLongPressedName(string name, string typed) {
if (name.size() > typed.size()) return false;
int i = 0, j = 0;
while (i < name.size() && j < typed.size()) {
if (name[i] != typed[j]) return false;
else {
int prev_i = i, prev_j = j;
while (i + 1 < name.size() && name[i + 1] == name[i]) ++ i;
while (j + 1 < typed.size() && typed[j + 1] == typed[j]) ++ j;
++ i;
++ j;
// 如果 typed[prev_j, ... j) 中重复字母的数量比
// name[prev_i, ..., i) 中的少, 返回 false.
if (j - prev_j < i - prev_i) return false;
}
}
return (i >= name.size() && j >= typed.size());
}
};