hiho字符串
描述:
如果一个字符串恰好包含2个’h’、1个’i’和1个’o’,文明就称这个字符串是hiho字符串。例如"olhateher"、"hugelnputhugeoutput"都是hiho字符串。
现在给定一个只包含小写字母的字符串S,小Hi想知道S的所有子串中,最短的hiho字符串是哪个。
输入:
找到S的所有子串中,最短的hiho字符串是哪个,输出该子串的长度。如果S的子串中没有hiho字符串,输出-1。
输出:
找到S的所有子串中,最短的hiho字符串是哪个,输出该子串的长度,如果S的子串中没有hiho字符串,输出-1。
思路: 遍历每个字符,每次遍历先进行判断是否包含hiho字符串的其中一个字符,如果有,设置好j的第一次位置,然后用j<w.length的第一次位置往后面扫,既要保证w[i]为其中字符,还要在每次扫的时候,进行containsAll总数判断是否够数,如果够数就,你懂的。
具体思路:
- 输入字符串
hiihpop
字符串转字符数组 - 定义好min,及 j = -1。
for (int i = 0; i < w.length; i++)
遍历字符数组w[]={hiihpop
}char c = w[i];
c = ‘h’ ,if (check(c))
c 是 hiho字符串的其中一个字符。j = i + 1;
j = 1。while(j < w.length)
从j往后扫。char c2 = w[i];
获取w[j] 这个字符 c2 = ‘i’。if (check(c2) && containsAll(w, i, j))
没有全部caontainsAll- 所以执行j++。 此时j=2。
- 然后获取 char c2 = w[j]; c2 = ‘i’。
- 然后判断边界,是否全部囊括。如果是则再判断是否是刚刚好数,如果是则替换min。。。。。。后面不讲了!
public class 尺取法例题 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
String s = sc.nextLine();
char[] w = s.toCharArray();
solve2(w);
}
public static void solve2(char[] w) {
int min = Integer.MAX_VALUE;
int j = -1;
for (int i = 0; i < w.length; i++) {
char c = w[i];
if (check(c)) { //i停下
if (j == -1)//j的第一次定位
j = i + 1;
while(j < w.length) {
char c2 = w[j];
if (check(c2) && containsAll(w, i, j)) {//全部囊括
if (check(w,i,j)&&j - i + 1 < min) { //更新min
min = j - i + 1;
}
break;//j停 下
}
j++;//j继续扫描
}
}
}
System.out.print(min == Integer.MAX_VALUE ? -1 : min);
}
private static boolean check(char c) {
return c == 'h' || c == 'i' || c == 'o';
}
private static boolean check(char[] w, int i, int j) {
int c1 = 0, c2 = 0, c3 = 0;
for (int k = i; k <= j; k++) {
if (w[k] == 'h') c1++;
if (w[k] == 'i') c2++;
if (w[k] == 'o') c3++;
}
return c1 == 2 && c2 == 1 && c3 == 1;
}
private static boolean containsAll(char[] w, int i, int j) {
int c1 = 0, c2 = 0, c3 = 0;
for (int k = i; k <=j; k++) {
if (w[k] == 'h') c1++;
if (w[k] == 'i') c2++;
if (w[k] == 'o') c3++;
}
return c1 >= 2 && c2 >= 1 && c3 >=1;
}
}