题目:
给定两个字符串 s1 和 s2,写一个函数来判断 s2 是否包含 s1 的某个变位词。
换句话说,第一个字符串的排列之一是第二个字符串的 子串 。
示例 1:
输入: s1 = "ab" s2 = "eidbaooo"
输出: True
解释: s2 包含 s1 的排列之一 ("ba").
示例 2:
输入: s1= "ab" s2 = "eidboaoo"
输出: False
提示:
1 <= s1.length, s2.length <= 104
s1 和 s2 仅包含小写字母
代码:
package jianzhioffer;
import java.util.Arrays;
public class offer_14 {
public static void main(String[] args) {
System.out.println(checkInckusion("ab","bakkkk"));
}
public static boolean checkInckusion(String s1, String s2) {
// 定义两个数组,分别用来存储两个字符串中的字符
int[] array1 = new int[26];
int[] array2 = new int[26];
int l1 = s1.length();
int l2 = s2.length();
if (l1 > l2) {
return false;
}
// 把每个字母转换为数组的下标,如果该字母存在,则下标加一,后续直接比较数组即可,数组相等则说明字符串相等
for (int i = 0; i < l1; i++) {
array1[s1.charAt(i) - 'a']++;
array2[s2.charAt(i) - 'a']++;
}
// 模拟滑动窗口
for (int i = l1; i < l2; i++) {
if (Arrays.equals(array1, array2)) {
return true;
}
// 开始滑动
array2[s2.charAt(i) - 'a'] ++;
array2[s2.charAt(i - l1) - 'a'] --;
}
return Arrays.equals(array1, array2);
}
}
解题思路:
首先这道题呢是非常经典的变位词问题,从长字符串中找短字符串的变位词。第一个要考虑的问题就是如何来记录字符串,我们选择的是通过数组来记录每个字母出现的次数,这样的话就不用考虑变位词的位置,直接看数组是否相等即可。先用一个数组来记录短字符串的,然后在另一个字符串上维护一个短字符串长度的滑动数组,来比较两个数组是否相等即可。
注意:
这道题的要求是只有小写字母,和17题要求不同,所以这道题可以减去 'a' 以后再记录字母,十七题大小写都有可能,则直接进行字母的记录。
注意刚开始的时候要比较一下两个字符串的长度,不符合题意的话就直接结束。