LeetCode:438. Find All Anagrams in a String(找出相同的子串的下標)
阿新 • • 發佈:2018-12-10
Given a string s and a non-empty string p, find all the start indices of p's anagrams in s.
Strings consists of lowercase English letters only and the length of both strings s and p will not be larger than 20,100.
The order of output does not matter.
Example 1:
Input: s: "cbaebabacd" p: "abc" Output: [0, 6] Explanation: The substring with start index = 0 is "cba", which is an anagram of "abc". The substring with start index = 6 is "bac", which is an anagram of "abc".
Example 2:
Input: s: "abab" p: "ab" Output: [0, 1, 2] Explanation:The substring with start index = 0 is "ab", which is an anagram of "ab". The substring with start index = 1 is "ba", which is an anagram of "ab". The substring with start index = 2 is "ab", which is an anagram of "ab".
方法1:(這種方法比較容易想到,但是效率應該是不高)
package leetcode; import org.junit.Test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; /** * @author zhangyu * @version V1.0 * @ClassName: FindAllAnagrams * @Description: TOTO * @date 2018/12/5 17:22 **/ public class FindAllAnagrams { @Test public void fun() { String s = "baa"; String p = "aa"; List<Integer> list= findAllAnagrams(s, p); System.out.println(list); } private List<Integer> findAllAnagrams(String s, String p) { //int [] indexs=new int[s.length()]; List<Integer> list = new ArrayList<>(); int i = 0; int j = p.length(); while (j <= s.length()) { String subString = s.substring(i, j); if (equalsIgnoreOrderString1(subString, p)) { list.add(i); } i++; j++; } //return Arrays.copyOfRange(indexs,0,count); return list; } public boolean equalsIgnoreOrderString1(String s, String p) { if (s.length() == 0 || p.length() == 0) { return false; } if (s.length() != p.length()) { return false; } char[] chsp = p.toCharArray(); for (char ch : chsp) { if (s.contains(String.valueOf(ch))) { s=s.replaceFirst(String.valueOf(ch), "@"); } else { return false; } } return true; } }
時間複雜度:O(n^3)
空間複雜度:O(n)
方法2:(一種比較高效的方法,利用陣列數字的方式)
package leetcode;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
/**
* @author zhangyu
* @version V1.0
* @ClassName: FindAllAnagrams
* @Description: TOTO
* @date 2018/12/5 17:22
**/
public class FindAllAnagrams2 {
@Test
public void fun() {
String s = "baa";
String p = "aa";
List<Integer> list = findAnagrams(s, p);
System.out.println(list);
}
public List<Integer> findAnagrams(String s, String p) {
List<Integer> ans = new ArrayList<>();
int sl = s.length(), pl = p.length();
if (sl < pl) {
return ans;
}
int[] pa = new int[26];
// 讓這些字元都對映在這26個數字中
for (char c : p.toCharArray()) {
System.out.println(pa[c - 'a']++);
}
int[] sa = new int[26];
char[] sc = s.toCharArray();
for (int i = 0; i < pl; i++) {
sa[sc[i] - 'a']++;
}
if (isSame(sa, pa)) {
ans.add(0);
}
for (int i = pl; i < sl; i++) {
sa[sc[i] - 'a']++;
sa[sc[i - pl] - 'a']--;
if (isSame(sa, pa)) ans.add(i - pl + 1);
}
return ans;
}
private boolean isSame(int[] sa, int[] pa) {
for (int i = 0; i < 26; i++) {
if (sa[i] != pa[i]) return false;
}
return true;
}
}
時間複雜度:O(n^2)
空間複雜度:O(n)