其他分享
首页 > 其他分享> > 力扣 392. 判断子序列---哈希思想与双指针查找

力扣 392. 判断子序列---哈希思想与双指针查找

作者:互联网

392. 判断子序列

给定字符串 s 和 t ,判断 s 是否为 t 的子序列。

字符串的一个子序列是原始字符串删除一些(也可以不删除)字符而不改变剩余字符相对位置形成的新字符串。(例如,"ace"是"abcde"的一个子序列,而"aec"不是)。

进阶:

如果有大量输入的 S,称作 S1, S2, … , Sk 其中 k >= 10亿,你需要依次检查它们是否为 T 的子序列。在这种情况下,你会怎样改变代码?

致谢:

特别感谢 @pbrother 添加此问题并且创建所有测试用例。

示例 1:

输入:s = “abc”, t = “ahbgdc”
输出:true
示例 2:

输入:s = “axc”, t = “ahbgdc”
输出:false

提示:
0 <= s.length <= 100
0 <= t.length <= 10^4
两个字符串都只由小写字符组成。

题解:(哈希思想直白复杂法)

开始想麻烦了,开始是将此问题分解为两个小问题:
1.要满足s的字母t里都有.
2.s的顺序问题。

故我分了两部分解决这两个问题。(见代码)

bool isSubsequence(char * s, char * t){
    int table[26]={0};//创建一个哈希表即可
    for(int i = 0;i<strlen(t);i++)
    {
        table[t[i]-'a']++;//先存上
    }
    for(int i=0;i<strlen(s);i++)
    {
        table[s[i]-'a']--;//再消耗,因此一个哈希即可完成操作
        if(table[s[i]-'a']<0)//则证明s有t没有的字母了
        {
            return 0;
        }//此为验证问题一的过程
    }
    int j = 0;
    for(int i=0;i<strlen(t);i++)
    {
        if(t[i]==s[j])//将t数组按顺序遍历依次与s比较,若相同了则二者均向后移位,否则只是移动t数组
        {
            j++;
        }
    }
    if(j==strlen(s))//验证是否遍历完了s,即顺序是否正确
        return 1;
    else
        return 0;
}

后来发现前面的问题一的解决所用代码是没有用的,因为按原代码解决问题二时也解决了问题一。

bool isSubsequence(char * s, char * t){
    int j = 0;
    for(int i=0;i<strlen(t);i++)
    {
        if(t[i]==s[j])
        {
            j++;
        }
    }
    if(j==strlen(s))
        return 1;
    else
        return 0;
}

以上是我不严格的“双指针”,下面为正经的双指针法:

bool isSubsequence(char * s, char * t){
    int j = 0,i = 0;//创建双指针,开始均指向头部
    while(j<strlen(t))//因为t数组是大的,所以找完t数组即可,因为要么找完t的同时也找完s了,要么就是没找完s。
    //因为在t数组大的情况下,若是没找完s的情况,则一定就是s不满足是t的子序列,所以也不用再找了
    {
        if(s[i]==t[j])
        {
            i++;
        }
        j++;
    }
    if(i==strlen(s))
        return 1;
    else
        return 0;
}

标签:力扣,char,return,int,++,---,392,哈希,序列
来源: https://blog.csdn.net/xiangguang_fight/article/details/112062369