将字符串中的元音字母排序
难度:
标签:
题目描述
Given a 0-indexed string s
, permute s
to get a new string t
such that:
- All consonants remain in their original places. More formally, if there is an index
i
with0 <= i < s.length
such thats[i]
is a consonant, thent[i] = s[i]
. - The vowels must be sorted in the nondecreasing order of their ASCII values. More formally, for pairs of indices
i
,j
with0 <= i < j < s.length
such thats[i]
ands[j]
are vowels, thent[i]
must not have a higher ASCII value thant[j]
.
Return the resulting string.
The vowels are 'a'
, 'e'
, 'i'
, 'o'
, and 'u'
, and they can appear in lowercase or uppercase. Consonants comprise all letters that are not vowels.
Example 1:
Input: s = "lEetcOde" Output: "lEOtcede" Explanation: 'E', 'O', and 'e' are the vowels in s; 'l', 't', 'c', and 'd' are all consonants. The vowels are sorted according to their ASCII values, and the consonants remain in the same places.
Example 2:
Input: s = "lYmpH" Output: "lYmpH" Explanation: There are no vowels in s (all characters in s are consonants), so we return "lYmpH".
Constraints:
1 <= s.length <= 105
s
consists only of letters of the English alphabet in uppercase and lowercase.
代码结果
运行时间: 72 ms, 内存: 17.4 MB
/*
题目思路:
1. 使用流操作提取和排序元音字母。
2. 使用列表保存元音字母的位置。
3. 构建新的字符串,将排序后的元音字母放在相应的位置。
*/
import java.util.*;
import java.util.stream.*;
public class Solution {
public String rearrangeVowels(String s) {
String vowels = "aeiouAEIOU";
List<Character> sortedVowels = s.chars()
.filter(c -> vowels.indexOf(c) != -1)
.mapToObj(c -> (char) c)
.sorted()
.collect(Collectors.toList());
Iterator<Character> vowelIterator = sortedVowels.iterator();
StringBuilder result = new StringBuilder();
for (char c : s.toCharArray()) {
if (vowels.indexOf(c) != -1) {
result.append(vowelIterator.next());
} else {
result.append(c);
}
}
return result.toString();
}
}
解释
方法:
该题解的核心思路是首先创建一个与输入字符串 `s` 等长的列表 `ans`,用于存储最终结果。接着,使用一个布尔列表 `rem` 来标记每个位置的字符是否为元音字母。同时,创建一个集合 `aei` 存储所有元音字母的小写和大写形式,用于快速判断某个字符是否为元音。在遍历字符串 `s` 的过程中,如果发现元音字母,则在 `rem` 中相应位置标记为 `True`,并将该元音字母添加到列表 `col` 中。遍历完成后,对 `col` 进行排序,按照 ASCII 值逆序排序。最后,再次遍历字符串,根据 `rem` 中的标记,从 `col` 中取出排序后的元音字母填充到 `ans` 中的相应位置。最终通过 `join` 方法将列表 `ans` 转换为字符串形式返回。
时间复杂度:
O(n + v log v)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么选择使用布尔列表`rem`来标记字符位置是否为元音,而不是直接在原字符串`s`上进行修改?
▷🦆
在`col.sort(key=lambda x: ord(x), reverse=True)`这一步中,为什么选择按ASCII值逆序排序元音字母,而题目要求是非递减顺序?
▷🦆
使用`pop()`方法从列表末尾取出元音字母填充到`ans`中,这种方法是否会影响到最终字符串的元音字母顺序,尤其是当元音字母排序后相同ASCII值的元音字母如何保证它们的相对位置不变?
▷