题目:
输入字符串s1和s2,如何找出字符串s2的所有变位词在字符串s1起始坐标?假设两个字符串只包含英文小写字母。例如,字符串s1为“cbadabacg”,字符串s2为“abc”,字符串s2的两个变位词“cba”和“bac”是字符串s1中的子字符串,输出它们在字符串s1起始下标0和5。
分析:
该题与剑指offer14思路完全一样,详细请看14题,时间复杂度O(n),空间复杂度O(1)。
该题因为要求存储字符串下标,所以利用了List集合来存储。

import java.util.LinkedList;
import java.util.List;

public class FindAnagrams {
public static void main(String[] args) {
String s1 = "cbadabacg";
String s2 = "abc";
List<Integer> anagrams = findAnagrams(s1, s2);
for (Integer anagram : anagrams) {
System.out.println(anagram);
}
}
public static List<Integer> findAnagrams(String s1,String s2){
List<Integer> indices = new LinkedList<>();
if (s1.length() < s2.length()){
return indices;
}
int[] counts = new int[26];
int i = 0;
for ( i = 0; i < s2.length(); ++i) {
counts[s2.charAt(i)-'a']++;
counts[s1.charAt(i)-'a']--;
}
if (areAllZero(counts)){
indices.add(0);
}
for (; i < s1.length() ; ++i) {
counts[s1.charAt(i)-'a']--;
counts[s1.charAt(i-s2.length())-'a']++;
if (areAllZero(counts)){
indices.add(i-s2.length()+1);
}
}
return indices;
}

private static boolean areAllZero(int[] counts) {
for (int count : counts) {
if (count!=0){
return false;
}
}
return true;
}
}

剑指offer15:字符串中的所有变位词_字符串