2020-10-21 第2题

2020-10-21 第2题

题目来源:leetcode 每日一题

925. 长按键入

你的朋友正在使用键盘输入他的名字 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.length <= 1000
typed.length <= 1000
name 和 typed 的字符都是小写字母。

  今天没有像昨天一样直接去看别人的题解,忍住了。这个题在简单的类别里,我好奇是怎么划分这三个类别的。

我觉得一开始我的思路有很多,但是很乱,最后我选了一个最容易理清楚的写:
  用两个游标,一个指当前字母,一个指后一个字母,两两一组,在typed字符串中如果能找到和name字符串出现顺序相同的两个字符就说明这一组成功,flag++(最后flag的值应该是name字符串的长度-1 ,如果想提高效率,可能加上一句,如果找不到直接退出会更快,一会儿试试----------------试完了,时空复杂度反倒下降了,不懂)。
  写完以后报错了,因为两种情况没有考虑:
  1、alex-alexxr(末尾多字符)
  2、alex-ssalex(开头多字符)
  我因为懒得想太多就直接加了两个判断,开头第一个字符必须和name[0]相同,结尾所有字符必须和name[name_len-1]相同。
  
  

class Solution {
public:
    bool isLongPressedName(string name, string typed) {
        int name_len=name.size();
        int typed_len=typed.size();
        int flag=0,i,j,vernier=0;
        char ver_pre,ver_cur,tmp_cur,tmp_pre,tail;
        for(i=0;i<name_len-1;i++)
        {
            ver_pre=name[i];
            ver_cur=name[i+1];
            for(j=vernier;j<typed_len;j++)
            {
                tmp_pre=typed[j];
                tmp_cur=typed[j+1];
                if(tmp_pre==ver_pre&&tmp_cur==ver_cur)
                {
                    flag++;
                    vernier=j+1;
                    break;
                }
                //else if(j+1==typed_len)
                   //return false;(不知道为什么加了这个时空复杂度反倒下降了......)
            }
        }
        if(flag!=name_len-1)
            return false;
        else 
        {
            //flag=0;
            tail=name[name_len-1];
            for(i=vernier;i<typed_len;i++)
            {
                if(typed[i]!=tail)
                    return false;
            }
            if(name[0]!=typed[0])
        	    return false;
            return true;
        }            
    }
};

运行结果如下,我其实不明白为什么运行第二遍效率涨了这么多,这到底是怎么算的?

在这里插入图片描述
在这里插入图片描述一会儿吃饭回来看别人的题解。不过代码长度和运行时间好像没什么太大的关系。

class Solution {
public:
    bool isLongPressedName(string name, string typed) {
        int j=0;
        for(int i=0;i<typed.size();i++){
            if(j==name.size()||typed[i]!=name[j])
            {
                if(i==0||typed[i]!=typed[i-1]) 
                return false;
  
            }
            else{
                j++;
            } 
        }
    if(j==name.size())
    return true;
    else return false;

    }
};
上方为空间复杂度最低的题解: name和typed从零开始遍历,当name字符串走完,或者typed中当前字符和name当前字符不匹配的时候进行判断,如果两个字符串第一个字符就不匹配那必然false,如果不是i==0,那就判断这个字符是不是长按造成的,如果不是,也false;如果name和typed的当前字符相同,那么就说明name中的字符有匹配,j++。最后看j和name的长度是否相等,相等就说明name中全部字符都有匹配。(那么alex-alexss这种它能判断吗?能,因为for循环的范围是typed整个的长度,其中的字符只有name匹配和长按两种来源,不符合的直接return false了)。

----------------------------------------

class Solution {
public:
    void table(string name,vector<pair<char,int>>& v1)
{
    for(int i = 0; i < name.size();i++)
        {
            if(v1.empty())
            {
                pair<char,int> p;
                p.first = name[i];
                p.second = 1;
                v1.push_back(p);
            }
            else
            {
                if(v1.back().first == name[i])
                    v1.back().second++;
                else
                {
                    pair<char,int> p;
                    p.first = name[i];
                    p.second = 1;
                    v1.push_back(p);
                }
            }
        }
}

  bool isLongPressedName(string name, string typed) {
        vector<pair<char,int>> v1;
        vector<pair<char,int>> v2;

       table(name,v1);
       table(typed,v2);

       if(v1.size() != v2.size()) return false;

       for(int i = 0; i < v1.size();i++)
       {
           if(v1[i].first != v2[i].first) return false;
           else if(v1[i].second > v2[i].second) return false;
       }

       return true;    
    }

};

上方为空间复杂度最高的题解(看了几个答案,我还是不太明白这时空复杂度怎么定的,提交相同答案获得不同时空使用情况):
我试图理解这个答案的题解思路,首先把name和typed中每个不同字符连续出现的个数用table函数进行数目统计,在主要判断函数中,首先判断两个用于统计的vector长度是否一致,不一致直接退出;如果字符出现的顺序不同(这个想法是我一开始的想法,我当时觉得写出来会麻烦,事实证明确实要用我不熟悉的pair和vector,统计每个字符顺序出现的次数),那直接false;如果字符出现顺序相同,就判断连续字符个数是否相同,如果name中的字符数>typed中的,那就说明typed不符合要求,直接退出;其余情况都符合要求。分析应该是数据结构用的比较多,所以空间复杂度较大。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值