notes/OJ notes/pages/Leetcode Permutation-In-String.md
2022-09-06 20:22:48 +08:00

2.2 KiB

Leetcode Permutation-In-String

2022-07-14 10:29

Algorithms:

#algorithm #sliding_window

Data structures:

#DS #string

Difficulty:

#coding_problem #difficulty_medium

Additional tags:

#leetcode #CS_list_need_understanding

Revisions:

N/A


Problem

Given two strings s1 and s2, return true if s2 contains a permutation of s1, or false otherwise.

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

Examples

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.

Thoughts

[!summary] This is a #sliding_window problem.

I tried to use kadane's algorithm, but the problem is a premature string, not set. So I gave up.

Then I found out this is sliding window problem, similar to Leetcode Longest-Substring-Without-Repeating-Characters

Solution

class Solution {
public:
  bool checkInclusion(string s1, string s2) {
    // Sliding windows problem.

    // First, register the freqs of s1
    vector<int> freq(26, 0);
    for (char ch : s1) {
      freq[ch - 'a']++;
    }

    // Second, start constructing window and window freq;
    int len = s1.length();
    int l = 0, r = 0;
    vector<int> window(26, 0);

    // Start expanding and sliding!
    while (r < s2.length()) {
      // I add value to window here, to avoid r OOB when r = s2.length
      window[s2[r] - 'a']++;
      if (r - l + 1 < len) {
        // Expand right
        r++;
      } else if (window == freq) { // note that I use else if, to make sure
                                   // every time r is incremented once.
        return true;
      } else {
        // Remove l from the window, slide right
        window[s2[l] - 'a']--;
        l++;
        r++;
      }
    }

    return false;
  }
};