567. Permutation in String

题目:

Given two strings s1 and s2, return true if s2 contains the permutation of s1.

In other words, one of s1's permutations is the substring of s2.

 

Example 1:

Input: s1 = "ab", s2 = "eidbaooo"
Output: true
Explanation: s2 contains one permutation of s1 ("ba").

Example 2:

Input: s1 = "ab", s2 = "eidboaoo"
Output: false

 

Constraints:

  • 1 <= s1.length, s2.length <= 104
  • s1 and s2 consist of lowercase English letters.

 

 

思路1:

这里用滑动窗口做,常规做法是两个哈希map,need存入需要的字符串,cur代表当前窗口的字符串。首先右端右移,如果需要当前字符,记录更新当前窗口。如果当前字符在窗口中的信息和need中相同,使valid加1,当valid与need的size相同时,我们确认true即可。然后是左端口右移并且更新窗口内数据,与前面对称的,如果当前字符在need中,则valid需要减1。最后如果循环结束未找到则返回false。

 

 

 

 

 

代码1:

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        unordered_map<char, int> need, cur;
        for(auto c:s1)
            need[c]++;
        int left=0, right=0, valid=0;
        while(right<s2.size()){
            char c=s2[right];
            right++;
            if(need.count(c)){
                cur[c]++;
                if(cur[c]==need[c])
                    valid++;
            }
            while(right-left>=s1.size()){
                if(valid==need.size())
                    return true;
                char d=s2[left];
                left++;
                if(need.count(d)){
                    if(need[d]==cur[d])
                        valid--;
                    cur[d]--;
                }
            }
        }
        return false;
    }
};

 

 

 

 

 

 

思路2:

其实也是滑动窗口的方法但是用了两个vector替代并且运行速度是要高于方法一的。首先是用大小为26的vector来记录s1中的字母频数。然后滑动窗口,每次如果当前窗口长度已经超过s1的长度,则右移左端口,然后右移右端口,这里其实是每次都移动一格,即端口向前移一步,每次移动结束后,判断两个记录的vector是否相同,如果相同则返回true。

 

 

 

 

 

代码2:

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        if(s1.size()>s2.size())
            return false;
        int n= s1.size();
        int m=s2.size();
        vector<int> v1(26);
        for(auto i:s1)
            v1[i-'a']++;
        vector<int> v2(26);
        for(int i=0;i<m;i++)
        {
            if(i>=n)
                v2[s2[i-n]-'a']--;
            v2[s2[i]-'a']++;
            if(v1==v2)
                return true;
        }
        return false;
        
        
        
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值