问题描述:
给你一个字符串 s ,请你返回满足以下条件的最长子字符串的长度:每个元音字母,即 ‘a’,‘e’,‘i’,‘o’,‘u’ ,在子字符串中都恰好出现了偶数次。
样例:
思路分析:
(1)刚开始没啥思路最直接的方法就是暴力破解法,直接二层循环解决。但是不出意外的超时了。
(2)看了官方解答后,它是利用前缀和、二进制、异或解决的。利用前缀和解决元素个数,利用二进制表示状态,利用异或解决元音字母偶数。
具体见代码注释:
package Leetcode;
import java.util.Arrays;
import java.util.Scanner;
public class Yyzczic {
//元音包含偶数次的最长字符字串
public static boolean check(String s)//判断字串是否符合情况
{
int value=0;
for (int j = 0; j <s.length() ; j++) {
if (s.charAt(j)=='a')
{
value++;
}
}
if (value%2!=0)
return false;
for (int j = 0; j <s.length() ; j++) {
if (s.charAt(j)=='e')
{
value++;
}
}
if (value%2!=0)
return false;
for (int j = 0; j <s.length() ; j++) {
if (s.charAt(j)=='i')
{
value++;
}
}
if (value%2!=0)
return false;
for (int j = 0; j <s.length() ; j++) {
if (s.charAt(j)=='o')
{
value++;
}
}
if (value%2!=0)
return false;
for (int j = 0; j <s.length() ; j++) {
if (s.charAt(j)=='u')
{
value++;
}
}
if (value%2!=0)
return false;
return true;
}
public static int findTheLongestSubstring(String s) {//暴力破解法
int max=0;
int len=s.length();
for (int i = 0; i <len ; i++) {
for (int j =i+1; j <=len ; j++) {
String temp=s.substring(i,j);
if (check(temp))
{
int templen=j-i;
if (templen>max)
max=templen;
}
}
}
return max;
}
public static int findTheLongestSubstring1(String s) {//前缀法
int[] statusMinPos = new int[1 << 5];
//初始化为非法下标
Arrays.fill(statusMinPos, -1);
//状态00000对应的最小位置显然是0
statusMinPos[0] = 0;
int ans = 0;
int curStatus = 0;
for (int i = 0; i < s.length(); i++) {
switch (s.charAt(i)) {
case 'a': {
curStatus ^=(1<<1);
}
break;
case 'e': {
curStatus ^= (1<<2);
}
break;
case 'i': {
curStatus ^= (1<<3);
}
break;
case 'o': {
curStatus ^= (1<<4);
}
break;
case 'u': {
curStatus ^= (1<<5);
}
break;
}
if (statusMinPos[curStatus] != -1) {
//该状态之前出现过,计算当前与之前出现的最小下标的距离
ans = Math.max(ans, i + 1 - statusMinPos[curStatus]);
} else {
//该状态未出现过,记录下一个位置。
statusMinPos[curStatus] = i + 1;
}
}
return ans;
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String s=scanner.nextLine();
System.out.println(findTheLongestSubstring1(s));
System.out.println(findTheLongestSubstring(s));
}
}
暴力破解会在如下出现超时:
执行结果如下: