leetcode之Long Pressed Name

Posted yutianzuijin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了leetcode之Long Pressed Name相关的知识,希望对你有一定的参考价值。

问题来源:Long Pressed Name
问题描述:判断字符串name是否是由长按字符串typed得来。长按含义是name的每个字符可能会重复1到多次。
看到该题目第一眼还以为是Is Subsequence,判断短串是否是长串的子序列,随即用该思路实现了一版,结果发现不对。原因在于在本题中要求的长按模式比子序列更为严格:首先name的开头和结尾字符要和typed的开头和结尾字符相同,此外typed的字符顺序要和name相同,中间不得插入其他字符。后来又想到另一种思路:把typed中前后相同的字符进行压缩,看压缩之后是否和name相同,结果一试也是不对。这种思路不对的原因是name中可能会出现连续相同的字符(比如leetcode中的ee),这种情况下不能把typed中相同的字符都压缩成一个字符。

解法一

上述第二种思路虽然不正确,但是却可以启发我们按照这种思路继续尝试,只要能处理好name中连续相同的字符即可。如果name中出现连续相同的字符,我们就让相同字符中前面的几个都只映射typed中一个字符,让相同字符中的最后一个映射typed中的一个或者多个字符。按照这个思路实现的正确代码如下:

bool isLongPressedName(string name, string typed) 
    int nlen=name.length(),tlen=typed.length();

    int j=0;//typed索引
    for(int i=0;i<nlen-1;i++)
    
        if(typed[j]!=name[i])
        
            return false;
        
            
		//当name前后字符相同时,前面的字符都只对应typed中的一个字符
        if(name[i]==name[i+1])
        
            j++;
        
        else
        
            while(j<tlen&&name[i]==typed[j])
            
                j++;
            
        

		//bad case2
        if(j==tlen) return false;
    

	//bad case1
    while(j<tlen&&name[nlen-1]==typed[j])
    
        j++;
    

    return j==tlen;

上述代码把name当做主遍历字符串,在每个位置判断是否匹配,并移动typed的索引。在代码实现的过程中,给定的bad case可能有这么几类:

  1. name匹配到末尾,但是typed没有匹配到末尾,例如:”abc”和”aabbccd”;
  2. name没有匹配到末尾,但是typed到末尾,例如:“pyplrz"和"ppyypllr”。
    只要能处理好各种bad case,把代码写对就水到渠成了。

解法二

在实现了上述方法之后又看了看题解,发现还有另一种解法:我们使用两个下标 i,j追踪name和typed的位置。当name[i]=typed[j]时,说明两个字符串存在一对匹配的字符,此时将i,j都加1。否则,如果typed[j]=typed[j−1],说明存在一次长按键入,此时只将j加1。最后,如果i=name.length,说明name的每个字符都被匹配了。按照该思路实现的正确代码如下:

bool isLongPressedName(string name, string typed) 
	//第一个字符必须相同,同时避免后续代码引入额外的边界判断
    if(name[0]!=typed[0]) return false;

	int nlen=name.length(),tlen=typed.length();
    int i=1,j=1;
    while(i<nlen||j<tlen)
    
        if(name[i]==typed[j]) 
        
            i++;j++;
        
        else if(typed[j]==typed[j-1])
        
            j++;
        
        else
        
            return false;
        
    

    return i==nlen&&j==tlen;

该思路本质上是把typed当做主遍历字符串,相比网上出现的正确代码,上面的代码逻辑判断更为简洁,书写也更加优美,推荐大家采用这种写法。

以上是关于leetcode之Long Pressed Name的主要内容,如果未能解决你的问题,请参考以下文章

Leetcode_easy925. Long Pressed Name

(Easy) Long Pressed Name LeetCode

[LeetCode&Python] Problem 925. Long Pressed Name

[LeetCode] 925. Long Pressed Name 长按键入的名字

Leetcode-925 Long Pressed Name(长按键入)

LeetCode.925-长按的名字(Long Pressed Name)