题目
给定一个字符串 s 和一个非空字符串 p,找到 s 中所有是 p 的字母异位词的子串,返回这些子串的起始索引。
字符串只包含小写英文字母,并且字符串 s 和 p 的长度都不超过 20100。
说明:
字母异位词指字母相同,但排列不同的字符串。
不考虑答案输出的顺序。
示例 1:
输入:
s: "cbaebabacd" p: "abc"
输出:
[0, 6]
解释:
起始索引等于 0 的子串是 "cba", 它是 "abc" 的字母异位词。
起始索引等于 6 的子串是 "bac", 它是 "abc" 的字母异位词。
示例 2:
输入:
s: "abab" p: "ab"
输出:
[0, 1, 2]
解释:
起始索引等于 0 的子串是 "ab", 它是 "ab" 的字母异位词。
起始索引等于 1 的子串是 "ba", 它是 "ab" 的字母异位词。
起始索引等于 2 的子串是 "ab", 它是 "ab" 的字母异位词。
方案:滑动窗口法
class Solution {
public List<Integer> findAnagrams(String s, String p) {
if(p.equals("")||p.length()>s.length()) return new LinkedList<Integer>();
char[] st = s.toCharArray( );
char[] pt = p.toCharArray( );
Arrays.sort(pt);
p=String.valueOf(pt);
LinkedList<Character> list = new LinkedList<>();
ArrayList<Integer> res = new ArrayList<>();
int plen = p.length();
int psum = 0;
int tsum = 0;
char[] tmp =new char[plen];
for (int t = 0 ; t<pt.length;t++
) {
psum += pt[t];
tsum += st[t];
tmp[t] = st[t];
}
boolean jud = false;
for (int i = 0;i<=s.length()-plen;i++){
if (i>0){
tsum = tsum-st[i-1]+st[i+plen-1];
tmp[(i-1)%plen] = st[i+plen-1];
}
if (tsum ==psum){
if (jud){
res.add(i);
}
else {
char[] t2 = tmp.clone();
Arrays.sort(t2);
if (Arrays.equals(t2,pt)) {
res.add(i);
jud = true;
}
}
}else jud = false;
}
return res;
}
}
复杂度计算
- 时间复杂度:O(n2)
- 空间复杂度:O(m+n) mn分别是俩字符串的长度,其他都是常数级的