問題:spa
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
Input:s1= "ab" s2 = "eidboaoo" Output: False
Note:string
解決:hash
① 給定兩個字符串s1和s2,問咱們s1的全排列的字符串任意一個是否爲s2的字串。it
雖然題目中有全排列的關鍵字,可是跟以前的全排列的題目的解法並不同,若是受思惟定勢影響比較深的話,很容易遍歷s1全部全排列的狀況,而後檢測其是否爲s2的子串,這種解法是很是不高效的,本題本質上能夠轉換爲求在必定範圍內(s1長度),字符與s1字符相同的狀況是否存在於字符串s2內。io
使用滑動窗口Sliding Window的思想來作:table
咱們先來分別統計s1和s2中前n1個字符串中各個字符出現的次數,其中n1爲字符串s1的長度,這樣若是兩者字符出現次數的狀況徹底相同,說明s1和s2中前n1的字符互爲全排列關係,那麼符合題意了,直接返回true。若是不是的話,那麼咱們遍歷s2以後的字符,對於遍歷到的字符,對應的次數加1,因爲窗口的大小限定爲了n1,因此每在窗口右側加一個新字符的同時就要在窗口左側去掉一個字符,每次都比較一下兩個哈希表的狀況,若是相等,說明存在。function
class Solution { //26ms
public boolean checkInclusion(String s1, String s2) {
int len1 = s1.length();
int len2 = s2.length();
if(len1 > len2) return false;
int[] h1 = new int[256];
int[] h2 = new int[256];
for (int i = 0;i < len1;i ++){
h1[s1.charAt(i)] ++;
h2[s2.charAt(i)] ++;
}
if (Arrays.equals(h1,h2)) return true;
for (int i = len1;i < len2;i ++){
h2[s2.charAt(i)] ++;
h2[s2.charAt(i - len1)] --;
if (Arrays.equals(h1,h2)) return true;
}
return false;
}
}
② 滑動窗口+hash table + 雙指針
class Solution { //15ms public boolean checkInclusion(String s1, String s2) { int len1 = s1.length(); int len2 = s2.length(); if(len1 > len2) return false; int[] hash = new int[256]; for (char c : s1.toCharArray()){ hash[c] ++; } int count = len1; char[] schar = s2.toCharArray(); int left = 0; int right = 0; while(right < len2){ if (hash[schar[right ++]] -- > 0) count --; while(count == 0){ if (right - left == len1) return true; if (hash[schar[left ++]] ++ == 0) count ++; } } return false; } }