题目描述
给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的排列。
换句话说,第一个字符串的排列之一是第二个字符串的子串。
示例1:
输入: s1 = "ab" s2 = "eidbaooo"
输出: True
解释: s2 包含 s1 的排列之一 ("ba").
示例2:
输入: s1= "ab" s2 = "eidboaoo"
输出: False
注意:
输入的字符串只包含小写字母
两个字符串的长度都在 [1, 10,000] 之间
解决方案提示:
滑动窗口
代码示例一
class Solution {
/**s1 = "ab" s2 = "eidbaooo"
* @param String $s1
* @param String $s2
* @return Boolean
*/
function checkInclusion($s1, $s2)
{
$s1Arr = str_split($s1);
$s2Arr = str_split($s2);
$s1Len = strlen($s1);
$s2Len = strlen($s2);
$map = array_slice($s2Arr, 0, $s1Len);
for ($i = $s1Len; $i <= $s2Len; $i++) {
if(array_count_values($s1Arr) == array_count_values($map)){
return true;
}
//维持一个固定长度的窗口
array_push($map, $s2Arr[$i]);
(count($map) == $s1Len + 1) && array_shift($map);
}
return false;
}
}
代码示例二
class Solution {
/**
* @param String $s1
* @param String $s2
* @return Boolean
*/
public static function checkInclusion($s1, $s2) {
$s1_len = strlen($s1);
$s2_len = strlen($s2);
if(!$s1_len || !$s1_len || $s1_len>$s2_len)return false;
$s1_arr = array();
$s2_arr = array();
for($i=0; $i<$s1_len; $i++){
$s1_arr[ord($s1[$i]) - ord('a')]++;
$s2_arr[ord($s2[$i]) - ord('a')]++;
}
if(self::isAnagram($s1_arr, $s2_arr)){
return true;
}
for($j=$s1_len; $j<$s2_len; $j++){
$s2_arr[ord($s2[$j-$s1_len]) - ord('a')]--;
$s2_arr[ord($s2[$j]) - ord('a')]++;
if(self::isAnagram($s1_arr, $s2_arr)){
return true;
}
}
return false;
}
public static function isAnagram($s1_arr, $s2_arr){
for($i=0; $i < 26; $i++){
if($s1_arr[$i] != $s2_arr[$i])return false;
}
return true;
}
}