Medium

题目描述

给你一个字符串 s,由小写英文单词组成,每个单词之间用单个空格分隔。

确定第一个单词中出现的元音字母数量。然后,反转每个具有相同元音数量的后续单词。保持所有其余单词不变。

返回结果字符串。

元音字母是 ‘a’、’e’、‘i’、‘o’ 和 ‘u’。

示例 1:

输入:s = "cat and mice"
输出:"cat dna mice"
解释:
第一个单词 "cat" 有 1 个元音。
"and" 有 1 个元音,所以它被反转为 "dna"。
"mice" 有 2 个元音,所以保持不变。
因此,结果字符串是 "cat dna mice"。

示例 2:

输入:s = "book is nice"
输出:"book is ecin"
解释:
第一个单词 "book" 有 2 个元音。
"is" 有 1 个元音,所以保持不变。
"nice" 有 2 个元音,所以它被反转为 "ecin"。
因此,结果字符串是 "book is ecin"。

示例 3:

输入:s = "banana healthy"
输出:"banana healthy"
解释:
第一个单词 "banana" 有 3 个元音。
"healthy" 有 2 个元音,所以保持不变。
因此,结果字符串是 "banana healthy"。

提示:

  • 1 <= s.length <= 10^5
  • s 由小写英文字母和空格组成
  • s 中的单词由单个空格分隔
  • s 不包含前导或尾随空格

解题思路

这道题目要求我们根据第一个单词的元音数量,对后续具有相同元音数量的单词进行反转。

解题思路:

  1. 解析字符串:将输入字符串按空格分割成单词数组,方便逐个处理。

  2. 计算元音数量:编写辅助函数来计算单词中的元音字母个数。元音字母包括 ‘a’、’e’、‘i’、‘o’、‘u’。

  3. 确定目标元音数:计算第一个单词的元音数量,这将作为判断标准。

  4. 处理后续单词:遍历从第二个单词开始的所有单词:

    • 计算当前单词的元音数量
    • 如果与第一个单词的元音数量相同,则反转该单词
    • 否则保持原样
  5. 重新组合:将处理后的单词用空格连接成最终结果。

算法复杂度分析:

  • 时间复杂度:O(n),其中 n 是字符串的长度,需要遍历每个字符
  • 空间复杂度:O(n),需要存储分割后的单词和结果字符串

这个解法直接按照题目要求模拟,逻辑清晰,实现简单。

代码实现

class Solution {
public:
    string reverseWords(string s) {
        vector<string> words;
        stringstream ss(s);
        string word;
        
        // 分割字符串
        while (ss >> word) {
            words.push_back(word);
        }
        
        if (words.empty()) return "";
        
        // 计算第一个单词的元音数量
        int targetVowels = countVowels(words[0]);
        
        // 处理后续单词
        for (int i = 1; i < words.size(); i++) {
            if (countVowels(words[i]) == targetVowels) {
                reverse(words[i].begin(), words[i].end());
            }
        }
        
        // 重新组合
        string result = words[0];
        for (int i = 1; i < words.size(); i++) {
            result += " " + words[i];
        }
        
        return result;
    }
    
private:
    int countVowels(const string& word) {
        int count = 0;
        for (char c : word) {
            if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
                count++;
            }
        }
        return count;
    }
};
class Solution:
    def reverseWords(self, s: str) -> str:
        words = s.split()
        
        if not words:
            return ""
        
        # 计算第一个单词的元音数量
        def count_vowels(word):
            return sum(1 for c in word if c in 'aeiou')
        
        target_vowels = count_vowels(words[0])
        
        # 处理后续单词
        for i in range(1, len(words)):
            if count_vowels(words[i]) == target_vowels:
                words[i] = words[i][::-1]
        
        return ' '.join(words)
public class Solution {
    public string ReverseWords(string s) {
        string[] words = s.Split(' ');
        
        if (words.Length == 0) return "";
        
        // 计算第一个单词的元音数量
        int targetVowels = CountVowels(words[0]);
        
        // 处理后续单词
        for (int i = 1; i < words.Length; i++) {
            if (CountVowels(words[i]) == targetVowels) {
                char[] chars = words[i].ToCharArray();
                Array.Reverse(chars);
                words[i] = new string(chars);
            }
        }
        
        return string.Join(" ", words);
    }
    
    private int CountVowels(string word) {
        int count = 0;
        foreach (char c in word) {
            if (c == 'a' || c == 'e' || c == 'i' || c == 'o' || c == 'u') {
                count++;
            }
        }
        return count;
    }
}
/**
 * @param {string} s
 * @return {string}
 */
var reverseWords = function(s) {
    const vowels = new Set(['a', 'e', 'i', 'o', 'u']);
    
    const countVowels = (word) => {
        let count = 0;
        for (let char of word) {
            if (vowels.has(char)) count++;
        }
        return count;
    };
    
    const words = s.split(' ');
    const firstWordVowelCount = countVowels(words[0]);
    
    for (let i = 1; i < words.length; i++) {
        if (countVowels(words[i]) === firstWordVowelCount) {
            words[i] = words[i].split('').reverse().join('');
        }
    }
    
    return words.join(' ');
};

复杂度分析

复杂度类型复杂度说明
时间复杂度O(n)n 为字符串长度,需要遍历每个字符计算元音数量和进行反转操作
空间复杂度O(n)需要存储分割后的单词数组和结果字符串