leetcode-master/problems/0925.长按键入.md

232 lines
7.3 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<p align="center">
<a href="https://programmercarl.com/other/kstar.html" target="_blank">
<img src="https://code-thinking-1253855093.file.myqcloud.com/pics/20210924105952.png" width="1000"/>
</a>
<p align="center"><strong><a href="https://mp.weixin.qq.com/s/tqCxrMEU-ajQumL1i8im9A">参与本项目</a>,贡献其他语言版本的代码,拥抱开源,让更多学习算法的小伙伴们收益!</strong></p>
# 925.长按键入
[力扣题目链接](https://leetcode.cn/problems/long-pressed-name/)
你的朋友正在使用键盘输入他的名字 name。偶尔在键入字符 c 按键可能会被长按而字符可能被输入 1 次或多次。
你将会检查键盘输入的字符 typed。如果它对应的可能是你的朋友的名字其中一些字符可能被长按那么就返回 True。
示例 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[i] 和 typed[j]相同则i++j++ (继续向后对比)
* name[i] 和 typed[j]不相同
* 看是不是第一位就不相同了也就是j如果等于0那么直接返回false
* 不是第一位不相同就让j跨越重复项移动到重复项之后的位置再次比较name[i] 和typed[j]
* 如果 name[i] 和 typed[j]相同则i++j++ (继续向后对比)
* 不相同返回false
* 对比完之后有两种情况
* name没有匹配完例如name:"pyplrzzzzdsfa" type:"ppyypllr"
* type没有匹配完例如name:"alex" type:"alexxrrrrssda"
动画如下:
<img src='https://code-thinking.cdn.bcebos.com/gifs/925.长按键入.gif' width=600> </img></div>
上面的逻辑想清楚了不难写出如下C++代码:
```CPP
class Solution {
public:
bool isLongPressedName(string name, string typed) {
int i = 0, j = 0;
while (i < name.size() && j < typed.size()) {
if (name[i] == typed[j]) { // 相同则同时向后匹配
j++; i++;
} else { // 不相同
if (j == 0) return false; // 如果是第一位就不相同直接返回false
// j跨越重复项向后移动同时防止j越界
while(j < typed.size() && typed[j] == typed[j - 1]) j++;
if (name[i] == typed[j]) { // j跨越重复项之后再次和name[i]匹配
j++; i++; // 相同则同时向后匹配
}
else return false;
}
}
// 说明name没有匹配完例如 name:"pyplrzzzzdsfa" type:"ppyypllr"
if (i < name.size()) return false;
// 说明type没有匹配完例如 name:"alex" type:"alexxrrrrssda"
while (j < typed.size()) {
if (typed[j] == typed[j - 1]) j++;
else return false;
}
return true;
}
};
```
时间复杂度O(n)
空间复杂度O(1)
## 其他语言版本
### Java
```java
class Solution {
public boolean isLongPressedName(String name, String typed) {
int i = 0, j = 0;
int m = name.length(), n = typed.length();
while (i< m && j < n) {
if (name.charAt(i) == typed.charAt(j)) { // 相同则同时向后匹配
i++; j++;
}
else {
if (j == 0) return false; // 如果是第一位就不相同直接返回false
// 判断边界为n-1,若为n会越界,例如name:"kikcxmvzi" typed:"kiikcxxmmvvzzz"
while (j < n-1 && typed.charAt(j) == typed.charAt(j-1)) j++;
if (name.charAt(i) == typed.charAt(j)) { // j跨越重复项之后再次和name[i]匹配
i++; j++; // 相同则同时向后匹配
}
else return false;
}
}
// 说明name没有匹配完
if (i < m) return false;
// 说明type没有匹配完
while (j < n) {
if (typed.charAt(j) == typed.charAt(j-1)) j++;
else return false;
}
return true;
}
}
```
### Python
```python
i = j = 0
while(i<len(name) and j<len(typed)):
# If the current letter matches, move as far as possible
if typed[j]==name[i]:
while j+1<len(typed) and typed[j]==typed[j+1]:
j+=1
# special case when there are consecutive repeating letters
if i+1<len(name) and name[i]==name[i+1]:
i+=1
else:
j+=1
i+=1
else:
return False
return i == len(name) and j==len(typed)
```
### Go
```go
func isLongPressedName(name string, typed string) bool {
if(name[0] != typed[0] || len(name) > len(typed)) {
return false;
}
idx := 0 // name的索引
var last byte // 上个匹配字符
for i := 0; i < len(typed); i++ {
if idx < len(name) && name[idx] == typed[i] {
last = name[idx]
idx++
} else if last == typed[i] {
continue
} else {
return false
}
}
return idx == len(name)
}
```
### JavaScript
```javascript
var isLongPressedName = function(name, typed) {
let i = 0, j = 0;
const m = name.length, n = typed.length;
while(i < m && j < n){
if(name[i] === typed[j]){ // 相同则同时向后匹配
i++; j++;
} else {
if(j === 0) return false; // 如果是第一位就不相同直接返回false
// 判断边界为n-1,若为n会越界,例如name:"kikcxmvzi" typed:"kiikcxxmmvvzzz"
while(j < n - 1 && typed[j] === typed[j-1]) j++;
if(name[i] === typed[j]){ // j跨越重复项之后再次和name[i]匹配,相同则同时向后匹配
i++; j++;
} else {
return false;
}
}
}
// 说明name没有匹配完 例如 name:"pyplrzzzzdsfa" type:"ppyypllr"
if(i < m) return false;
// 说明type没有匹配完 例如 name:"alex" type:"alexxrrrrssda"
while(j < n) {
if(typed[j] === typed[j-1]) j++;
else return false;
}
return true;
};
```
### TypeScript
```typescript
function isLongPressedName(name: string, typed: string): boolean {
const nameLength: number = name.length,
typeLength: number = typed.length;
let i: number = 0,
j: number = 0;
while (i < nameLength && j < typeLength) {
if (name[i] !== typed[j]) return false;
i++;
j++;
if (i === nameLength || name[i] !== name[i - 1]) {
// 跳过typed中的连续相同字符
while (j < typeLength && typed[j] === typed[j - 1]) {
j++;
}
}
}
return i === nameLength && j === typeLength;
};
```
-----------------------
<div align="center"><img src=https://code-thinking.cdn.bcebos.com/pics/01二维码一.jpg width=500> </img></div>