[Leetcode] 345. Reverse Vowels of a String

Description:
Write a function that takes a string as input and reverse only the vowels of a string.

Example 1:
Given s = “hello”, return “holle”.

Example 2:
Given s = “leetcode”, return “leotcede”.

Note:
The vowels does not include the letter “y”.

解法一:
基本思想:set的使用,对撞指针。
思路:将元音字母存入set中,利用set的.find()方法,返回的是找到的元素的下标,否则返回.end()。对撞指针用于从头从尾找到元音然后进行swap。
Time: O(n^2)
Space: O(1)

class Solution {
public:
    string reverseVowels(string s) {
        if(s.size() == 0)
            return s;

        set<char> vowels = {'A','E','I','O','U','a','e','i','o','u'}; //因为无需排序,可以直接用unordered_set

        int i = 0, j = s.size() - 1;
        while(i < j){
            while(vowels.find(s[i])==vowels.end()) //set的find()时间复杂度O(logn), unordered_set的find()时间复杂度O(1)
                i++;
            while(vowels.find(s[j])==vowels.end())
                j--;
            if(i >= j) //注意是>=,不是==,如果是i==j则有可能在swap过一次以后,i遍历到原j位置,j遍历到原i位置,然后又swap回来了,此时i>j
                break;
            if(s[i]!=s[j])
                swap(s[i],s[j]);//对于都是元音时,不论是否swap,都要i++,j--,因此i++,j--不能写在括号里
            i++; 
            j--;
        }
        return s;
    }
};

算法细节:

  • 在判断i,j是否相遇时,不能写if(i==j),要写if(i>=j),这是因为有可能i,j直接跨越了等于的条件,直接变成i>j,如在“hello”的输入中,元音第一次交换,变成“holle”,然后i到达了j原来的位置,j到达了i原来的位置,此时i不等于j,i>j,如果是if(i==j)那么它们又会换回来,最终输出“hello”,这是有问题的。
  • 在存元音到set中时,由于可以是无序的,那么可以使用unordered_set来存。set的find函数时间复杂度O(logn)(底层采用平衡树),而unordered_set的查找函数.find()时间复杂度是O(1)。(底层采用哈希表)
  • 注意swap完之后的i++,j–不能写在中括号中间,因为判断两个元音是否相等是为了减少unnecessary swap,不管这两个元音是否swap,都要继续前进,也就是i++,j–

解法二:
基本思想:巧用ASCII范围。

class Solution {
public:
    string reverseVowels(string s) {
        int dict[256] = {0};
        dict['a'] = 1, dict['A'] = 1;
        dict['e'] = 1, dict['E'] = 1;
        dict['i'] = 1, dict['I'] = 1;
        dict['o'] = 1, dict['O'] = 1;
        dict['u'] = 1, dict['U'] = 1;
        int i = 0, j = (int)s.size() - 1;
        while(i < j){
            while(i < j && dict[s[i]] == 0) i++;
            while(i < j && dict[s[j]] == 0) j--;
            swap(s[i],s[j]);
            i++;j--;
        }
        return s;
    }
};

算法细节:

  • 同样注意swap完之后的i++,j–不能写在中括号中间,因为判断两个元音是否相等是为了减少unnecessary swap,不管这两个元音是否swap,都要继续前进,也就是i++,j–
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值