438. Find all the letter ectopic words in the string

Posted by andylai on Sun, 28 Nov 2021 18:19:39 +0100

438. Find all letter words in the string

Medium difficulty
Given two strings S and p, find the substrings of all ectopic words of p in s, and return the starting indexes of these substrings. The order in which answers are output is not considered.

Ectopic words refer to strings formed by rearrangement of the same letters (including the same string).

Example 1:

Input: s = "cbaebacd", p = "abc"
Output: [0,6]
Explanation:
The substring with the starting index equal to 0 is "cba", which is an ectopic word of "abc".
The substring with the starting index equal to 6 is "bac", which is an ectopic word of "abc".
Example 2:

Input: s = "abab", p = "ab"
Output: [0,1,2]
Explanation:
The substring with the starting index equal to 0 is "ab", which is an ectopic word of "ab".
The substring with the starting index equal to 1 is "ba", which is an ectopic word of "ab".
The substring with the starting index equal to 2 is "ab", which is an ectopic word of "ab".

Tips:

  • 1 <= s.length, p.length <= 3 * 104
  • s and p contain only lowercase letters

Problem solution

Idea: Violence
 hold p Full Permutation of (not feasible)
judge s Does it contain

perhaps

Analogy: pattern matching
 hold p Arrange in ascending alphabetical order to get a new one p
 The results of each match are arranged in ascending alphabetical order with the new ones p Comparison,
The comparison can be performed by XOR operation

perhaps

Give what you ask p The letters in are converted into a unique number( ACII Code)
Give what you ask p The only result (XOR) obtained by converting these numbers into some operation

code

It's not easy to find. Just look at the official answer
 And XOR does not necessarily guarantee the uniqueness of the result

official

Method 1: sliding window
thinking

According to the requirements of the topic, we need to find the ectopic word of string p in string s. Because the length of the ectopic word of string p must be the same as that of string p, we can construct a sliding window with the same length as that of string p in string s, and maintain the number of each letter in the window; When the number of each letter in the window is the same as that in string p, it indicates that the current window is an ectopic word of string p.

algorithm

In the implementation of the algorithm, we can use an array to store the string p and the number of each letter in the sliding window.

details

When the length of string s is less than the length of string p, there must be no ectopic word of string p in string s. However, since a window with the same length as that of string p cannot be constructed in string s, this situation needs to be handled separately.

code

Author: leetcode solution
Link: https://leetcode-cn.com/problems/find-all-anagrams-in-a-string/solution/zhao-dao-zi-fu-chuan-zhong-suo-you-zi-mu-xzin/
Source: LeetCode
The copyright belongs to the author. For commercial reprint, please contact the author for authorization, and for non-commercial reprint, please indicate the source.

class Solution {
    public List<Integer> findAnagrams(String s, String p) {
        int sLen = s.length(), pLen = p.length();

        if (sLen < pLen) {
            return new ArrayList<Integer>();
        }

        List<Integer> ans = new ArrayList<Integer>();
        int[] sCount = new int[26];
        int[] pCount = new int[26];
        for (int i = 0; i < pLen; ++i) {
            ++sCount[s.charAt(i) - 'a'];
            ++pCount[p.charAt(i) - 'a'];
        }

        if (Arrays.equals(sCount, pCount)) {
            ans.add(0);
        }

        for (int i = 0; i < sLen - pLen; ++i) {
            --sCount[s.charAt(i) - 'a'];
            ++sCount[s.charAt(i + pLen) - 'a'];

            if (Arrays.equals(sCount, pCount)) {
                ans.add(i + 1);
            }
        }

        return ans;
    }
}

unscramble

Use the following statement to s and p Conversion of,
 for (int i = 0; i < pLen; ++i) {
            ++sCount[s.charAt(i) - 'a'];
            ++pCount[p.charAt(i) - 'a'];
        }
  hold s and p Into two counter arrays sCount and pCount[
  The problem turns into sCount seek pCount
   for (int i = 0; i < sLen - pLen; ++i) {
            --sCount[s.charAt(i) - 'a'];
            ++sCount[s.charAt(i + pLen) - 'a'];

            if (Arrays.equals(sCount, pCount)) {
                ans.add(i + 1);
            }
        }
  The above is window sliding, sliding only one bit at a time, and then comparing

Topics: data structure