当一个字符串满足如下条件时,我们称它是 美丽的 :
- 所有 5 个英文元音字母(
'a'
,'e'
,'i'
,'o'
,'u'
)都必须 至少 出现一次。 - 这些元音字母的顺序都必须按照 字典序 升序排布(也就是说所有的
'a'
都在'e'
前面,所有的'e'
都在'i'
前面,以此类推)
比方说,字符串 "aeiou"
和 "aaaaaaeiiiioou"
都是 美丽的 ,但是 "uaeio"
,"aeoiu"
和 "aaaeeeooo"
不是美丽的 。
给你一个只包含英文元音字母的字符串 word
,请你返回 word
中 最长美丽子字符串的长度 。如果不存在这样的子字符串,请返回 0
。
子字符串 是字符串中一个连续的字符序列。
示例 1:
输入:word = "aeiaaioaaaaeiiiiouuuooaauuaeiu" 输出:13 解释:最长子字符串是 "aaaaeiiiiouuu" ,长度为 13 。
示例 2:
输入:word = "aeeeiiiioooauuuaeiou" 输出:5 解释:最长子字符串是 "aeiou" ,长度为 5 。
示例 3:
输入:word = "a" 输出:0 解释:没有美丽子字符串,所以返回 0 。
1.首先如果数组长度小于5的话,不可能满足美丽的定义,将这种情况提前排除
2.遍历时分了几种情况判断:
- 如果当前字符比上一个不小(顺序意义),那么当前子串长度+1
- 如果当前字符比上一个大,那么子串中元音字母种类+1
- 如果当前字符比上一个小,那么肯定当前字串不美丽,以当前字符为首继续进行遍历
3.如果当前子字符串没有以a开头的话,那么在进行下一个子字符串开始遍历之前,元音种类一定不会达到5,所以只要判断种类即可
4.当元音种类为5的时候,持续维护更新最终结果,取出最大值即可
class Solution {
public int longestBeautifulSubstring(String word) {
if (word.length()<5)return 0;
char[] arr = word.toCharArray();
int res=0;
int rlen=1;
int vowel=1;
for(int i=1;i<word.length();i++){
if(arr[i]>=arr[i-1]) rlen++;
if(arr[i]>arr[i-1]) vowel++;
if(arr[i]<arr[i-1]) {rlen=1;vowel=1;}
if(vowel==5) {res=rlen>res?rlen:res;}
}
return res;
}
}
第二种方法滑动窗口
java 中的Set中的数组不能重复 所以用set数组存放5个元音字母
这种求满足某种条件的子字符串问题,是典型的滑动窗口套路题了。
这种题的思路一般是设置一个滑动窗口,每次试探地将元素从右侧加入窗口,如果满足条件则顺利加入;如果遇到的元素加入后使得条件变得不满足,那么试图从左侧移除元素,直到条件满足。
在窗口滑动的过程中,右指针和左指针的移动分别有如下规律:
右指针
right++ 即只向右移动一个位置,每次试探一个新元素。
左指针
left++ 向右移动一个位置
left=right 即清空窗口中所有元素
left移到窗口中某个合适位置(比如刚好使得窗口中没有重复元素-lC003题)
本题中窗口要满足的条件即元素按字典序排列和5个元音字母必须全部出现,对于第一个条件只需要比较新元素和窗口中元素的字典序即可,对于第二个条件我们使用一个hash set来统计窗口中字符的种类。
class Solution {
public int longestBeautifulSubstring(String word) {
List<Character> window=new ArrayList<Character>();
Set<Character> set = new HashSet<Character>();
int left=0;
int res = 0;
int right=0;
while(right<word.length()) {
if (window.isEmpty() || word.charAt(right)>=window.get(window.size()-1)) {
window.add(word.charAt(right));
set.add(word.charAt(right));
if (set.size()==5) {
res=Math.max(res, window.size());
}
}else {
window.clear();
set.clear();
left=right;
window.add(word.charAt(left));
set.add(word.charAt(left));
}
right++;
}
return res;
}
}