版权声明:本文为博主原创文章,转载请注明出处! https://blog.csdn.net/ASN_forever/article/details/85013363
原始思路1: 获取p串的全排列,与s暴力对比
但这种方法时间复杂度太高,主要是因为全排列的复杂度太高,如果p字符串长度为n的话,那么全排列复杂度为O(n!)。严重超时。
public class Test {
Set<String> set = new HashSet<String>();
public static void main(String[] args) {
String s = "cbadecbabacdcbabdcadbc";
String p = "abcd";
Test t = new Test();
List<Integer> list = t.findAnagrams(s, p);
for (int i : list) {
System.out.print(i + " ");
}
}
public List<Integer> findAnagrams(String s, String p) {
List<Integer> list = new ArrayList<Integer>();
char[] arr = p.toCharArray();
fun(arr, 0);
for (int i = 0; i <= s.length() - p.length(); i++) {
if (set.contains(s.substring(i, i + p.length()))) {
list.add(i);
}
}
return list;
}
public void fun(char[] arr, int index) {
if (index == arr.length) {
set.add(String.valueOf(arr));
return;
}
for (int i = index; i < arr.length; i++) {
swap(arr, index, i);
fun(arr, index + 1);
swap(arr, index, i);
}
}
public void swap(char[] arr, int i, int j) {
char temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
}
原始思路2:截取p长度的字符串排序比较
思路是先将p进行排序,然后在遍历s,每次遍历p个长度,并排序,然后与经过排序的p进行比较。
遗憾的是,也超时了。在测试用例全是一长串“a”的时候,超出了时间限制。
public List<Integer> findAnagrams(String s, String p) {
List<Integer> list = new ArrayList<Integer>();
if(s.length() < p.length() || s == null || p == null){
return list;
}
char[] pArr = p.toCharArray();
Arrays.sort(pArr);
String strP = String.valueOf(pArr);
int len = p.length();
for(int i=0;i<=s.length()-len;i++){
if(s.substring(i, i+len).equals(p)){
list.add(i);
}else{
char[] sArr = s.substring(i, i+len).toCharArray();
Arrays.sort(sArr);
if(String.valueOf(sArr).equals(strP)){
list.add(i);
}
}
}
return list;
}
正规解法:滑动窗口法
表示没看太懂。感觉这种方法的关键部分是每比较一遍后,在进行下一轮比较前,需要复位。
public List<Integer> findAnagrams(String s, String p) {
List<Integer> result = new ArrayList<Integer>();
char[] sArr = s.toCharArray();
char[] pArr = p.toCharArray();
int[] word = new int[26];
for(char ch : pArr){
word[ch-'a']++;
}
int start = 0;
for(int i=0;i<sArr.length;i++){
int cIndex = sArr[i]-'a';
word[cIndex]--;
while(word[cIndex]<0){
word[sArr[start]-'a']++;
start++;
}
if(i-start+1 == pArr.length){
result.add(start);
word[sArr[start]-'a']++;
start++;
}
}
return result;
}