思路一:
- A[]用來表明有哪些字母出現(xiàn)在s1中,出現(xiàn)了幾次供炎。無需記錄字母的位置宪哩,因?yàn)轭}目中要求的是任意排列娩贷,只需記錄次數(shù)。
- System.arraycopy函數(shù)是深拷貝锁孟,將A[]的內(nèi)容拷貝給B[]彬祖。
- B[]減去s2中出現(xiàn)的字母及其次數(shù),一旦出現(xiàn)不屬于s1的字母品抽,那么當(dāng)前子串不滿足條件储笑,進(jìn)入下一個子串,(!)要再次copy完整的A[]給B[]圆恤。出現(xiàn)屬于s1的字母突倍,就減1。
- 如果B[]和C[]相等盆昙,C[]為全0數(shù)組羽历,說明s2中含有s1中所有字母的一個排列,返回true淡喜。
代碼java:
class Solution {
public boolean checkInclusion(String s1, String s2) {
int[] A = new int[128];
for (int i = 0; i < s1.length(); i++) {
int value = Integer.valueOf(s1.charAt(i));
A[value]++;
}
int[] B = new int[128];
int[] C = new int[128];//全0的數(shù)組秕磷,用于比較
for (int i = 0; i < s2.length(); i++) {
System.arraycopy(A, 0, B, 0, A.length);
for(int j=i;j<s2.length();j++) {
if(B[Integer.valueOf(s2.charAt(j))] == 0) {//子串中出現(xiàn)不屬于s1的字母,直接退出
break;
}
B[Integer.valueOf(s2.charAt(j))]--;
}
if (Arrays.equals(B, C)) {
return true;
}
}
return false;
}
}
思路二:
- 根據(jù)大佬的c++代碼寫的炼团。在c++中有vector類型澎嚣,比較起來更加方便,java中我用數(shù)組代替瘟芝。
- 兩個數(shù)組arr1[]易桃,arr2[]也是用來記錄s1,s2中出現(xiàn)的字母及其次數(shù)锌俱。首先晤郑,先比較s2中前l(fā)en1個字母組成的子串是否是s1的一個排列,如果是贸宏,返回true造寝。否則,繼續(xù)比較锚赤。
利用s2中子串的長度必須與s1的長度相等這一特點(diǎn)匹舞,每次加入新的字符,就刪去前面一個字符线脚,這樣長度一直相等赐稽,且是子串叫榕。 - 注意!數(shù)組的內(nèi)容是否相等要用Arrays.equal函數(shù)姊舵,arr1.equals(arr2)不可以晰绎。
class Solution {
public boolean checkInclusion(String s1, String s2) {
int len1=s1.length();
int len2=s2.length();
if(len1>len2 || len1==0) {
return false;
}
int[] arr1=new int[128];
int[] arr2=new int[128];
for(int i=0;i<len1;i++) {
int value1=Integer.valueOf(s1.charAt(i));
arr1[value1]++;
int value2=Integer.valueOf(s2.charAt(i));
arr2[value2]++;
}
if(Arrays.equals(arr1,arr2 )) {
return true;
}
for(int i=len1;i<len2;i++) {
int value2=Integer.valueOf(s2.charAt(i));
arr2[value2]++;//裝新的字符
int value22=Integer.valueOf(s2.charAt(i-len1));
arr2[value22]--;//刪除早裝入的字符,加一個刪一個可以始終保持 當(dāng)前正在比較的子串所形成的arr2的長度與s1的長度相同!括丁!
if(Arrays.equals(arr1,arr2 )) {
return true;
}
}
return false;
}
}