- 给定字符串str1和str2,求str1的子串中含有str2所有字符的最小子串长度
【举例】
str1="abcde",str2="ac"
因为"abc"包含 str2 所有的字符,并且在满足这一条件的str1的所有子串中,"abc"是 最短的,返回3。
str1="12345",str2="344" 最小包含子串不存在,返回0。
/**
* 给定字符串str1和str2,求str1的子串中含有str2所有字符的最小子串长度
* 【举例】
* str1="abcde",str2="ac"
* 因为"abc"包含 str2 所有的字符,并且在满足这一条件的str1的所有子串中,"abc"是 最短的,返回3。
* str1="12345",str2="344" 最小包含子串不存在,返回0。
*/
public class MinSubStrLen {
// 建立词频表,和统计str2字符总数all
// 遍历str1每到一个位置让相应词频表--,all--
// 当all小于0时移动L,
public static int minSubStrLen(String str1,String str2){
char[] c1 = str1.toCharArray();
char[] c2 = str2.toCharArray();
// 字符从0~255,比如'a'字符的个数用map[a] = 1
int[] map = new int[256];
for(int i = 0;i < c2.length;i++){
map[c2[i]] += 1;
}
int all = str2.length();
int left = 0;
int right = 0;
int min = Integer.MAX_VALUE;
while (right < str1.length()){
map[c1[right]]--;
if(map[c1[right]] >= 0){
all--;
}
if(all == 0){
// 已经把str2遍历完了,缩小left,left往右移动的过程中只要保持all = 0,那么就是符合题意的子串
// 当left移动到使all > 0 的时候收集第一当前最小的答案
while (map[c1[left]] < 0){
map[c1[left++]] ++;
// 此时all用增加left向右继续移动
}
// 当移动到一个位置,使得词频表中的某个字符大于0
min = Math.min(min,right-left+1);
all++;
map[c1[left++]]++;
}
right ++;
}
return min == Integer.MAX_VALUE ? 0 : min;
}
public static void main(String[] args) {
String str1 = "abcde";
String str2 = "ac";
System.out.println(minSubStrLen(str1, str2));
}
}