567. Permutation in String


Given two strings s1 and s2, write a function to return true if s2 contains the permutation of s1. In other words, one of the first string’s permutations is the substring of the second string.

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

Note:

  1. The input strings only contain lower case letters.
  2. The length of both given strings is in range [1, 10,000].

方法1: sliding window + vector

参见438. Find All Anagrams in a String
花花:http://zxi.mytechroad.com/blog/hashtable/leetcode-438-find-all-anagrams-in-a-string/

易错点

  1. 题目要求是s2 contains s1, 看清楚

Complexity

Time complexity: O(n)
Space complexity: O(n)

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

方法2: sliding window (two pointers)+ hash

discussion: https://leetcode.com/problems/permutation-in-string/discuss/102590/8-lines-slide-window-solution-in-Java

思路:

首先建立一下目标string,也就是s1的计数hash,然后开始遍历s2。用左右指针维持一个sliding window,前进的规则是:对于右指针,每次前进会将hash中的count–,如果出现了count < 0, 说明出现了不应该出现的字符,这时候右指针停止前进。左指针此时出发,开始消掉seen characters,也就是说,每向前滑动,会将count++。我们的目的是将那个count < 0 的fix掉,所以任何一个count被左指针回复为 count == 0,目的就达到了,右指针可以继续前进。

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        unordered_map<char, int> hash;
        
        for (char c: s1) hash[c]++;
        for (int left = 0, right = 0; right < s2.size(); right++) {
            if (--hash[s2[right]] < 0) {
                while (++hash[s2[left++]] != 0) {};
            }
            else if (right - left + 1 == s1.size()) return true;
        }
        return s1.size() == 0;
    }
};

方法3: sliding window (two pointer) + hash + count

class Solution {
public:
    bool checkInclusion(string s1, string s2) {
        unordered_map<char, int> hash;
        
        for (char c: s1) hash[c]++;
        int count = 0;
        for (int left = 0, right = 0; right < s2.size(); right++) {
            if (--hash[s2[right]] >= 0) {
                count ++;
            }
            else {
                while (++hash[s2[left++]] > 0) {
                    count--;
                } 
            }
            if (count == s1.size()) return true;
        }
        return s1.size() == 0;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值