LeetCode438題:找到字串中所有字母異位詞
阿新 • • 發佈:2018-12-26
原始思路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; }