Problem#
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.
Examples#
Example 1#
1
2
3
Input: name = "alex" , typed = "aaleex"
Output: true
Explanation: 'a' and 'e' in ' alex' were long pressed.
Example 2#
1
2
3
Input: name = "saeed" , typed = "ssaaedd"
Output: false
Explanation: 'e' must have been pressed twice, but it was not in the typed output.
Constraints#
1 <= name.length, typed.length <= 1000
name
and typed
consist of only lowercase English letters.
Solution#
Method 1 – Two Pointers (1)#
Intuition#
We use two pointers to compare the name
and typed
strings. If the current characters match, move both pointers. If the current character in typed
matches the previous character in typed
, it’s a long press, so move the typed
pointer. Otherwise, return false.
Approach#
Initialize two pointers, i
for name
and j
for typed
.
While j
is less than the length of typed
:
If i
is less than the length of name
and name[i] == typed[j]
, increment both i
and j
.
Else if j > 0
and typed[j] == typed[j-1]
, increment j
(long press).
Else, return false.
After the loop, check if i
has reached the end of name
.
Return true if so, otherwise false.
Code#
Cpp
Go
Java
Kotlin
Python
Rust
Typescript
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
public :
bool isLongPressedName(string name, string typed) {
int i = 0 , j = 0 ;
while (j < typed.size()) {
if (i < name.size() && name[i] == typed[j]) {
i++ ; j++ ;
} else if (j > 0 && typed[j] == typed[j- 1 ]) {
j++ ;
} else {
return false;
}
}
return i == name.size();
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
func isLongPressedName (name string , typed string ) bool {
i , j := 0 , 0
for j < len(typed ) {
if i < len(name ) && name [i ] == typed [j ] {
i ++
j ++
} else if j > 0 && typed [j ] == typed [j - 1 ] {
j ++
} else {
return false
}
}
return i == len(name )
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
public boolean isLongPressedName (String name, String typed) {
int i = 0, j = 0;
while (j < typed.length ()) {
if (i < name.length () && name.charAt (i) == typed.charAt (j)) {
i++ ; j++ ;
} else if (j > 0 && typed.charAt (j) == typed.charAt (j- 1)) {
j++ ;
} else {
return false ;
}
}
return i == name.length ();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class Solution {
fun isLongPressedName (name: String, typed: String): Boolean {
var i = 0 ; var j = 0
while (j < typed.length) {
if (i < name.length && name[i] == typed[j]) {
i++ ; j++
} else if (j > 0 && typed[j] == typed[j-1 ]) {
j++
} else {
return false
}
}
return i == name.length
}
}
1
2
3
4
5
6
7
8
9
10
11
12
class Solution :
def isLongPressedName (self, name: str, typed: str) -> bool:
i = j = 0
while j < len(typed):
if i < len(name) and name[i] == typed[j]:
i += 1
j += 1
elif j > 0 and typed[j] == typed[j- 1 ]:
j += 1
else :
return False
return i == len(name)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
impl Solution {
pub fn is_long_pressed_name (name: String, typed: String) -> bool {
let (mut i, mut j) = (0 , 0 );
let name = name.as_bytes();
let typed = typed.as_bytes();
while j < typed.len() {
if i < name.len() && name[i] == typed[j] {
i += 1 ;
j += 1 ;
} else if j > 0 && typed[j] == typed[j- 1 ] {
j += 1 ;
} else {
return false ;
}
}
i == name.len()
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Solution {
isLongPressedName (name : string , typed : string ): boolean {
let i = 0 , j = 0 ;
while (j < typed .length ) {
if (i < name .length && name [i ] === typed [j ]) {
i ++ ;
j ++ ;
} else if (j > 0 && typed [j ] === typed [j - 1 ]) {
j ++ ;
} else {
return false ;
}
}
return i === name .length ;
}
}
Complexity#
⏰ Time complexity: O(n + m)
, where n is the length of name
and m is the length of typed
. Each character is checked at most once.
🧺 Space complexity: O(1)
, only a few pointers are used.