如何在Python中反转字符串中的元音(详细教程)

246 阅读3分钟

目录

公司标签。 谷歌、亚马逊、Facebook

根据不同程序员的报告,这是谷歌面试中经常被问到的问题之一。如果这个问题在你的面试中被问到,你能以最佳方式解决它吗?

问题说明

给定一个字符串s,只反转字符串中的所有元音并返回。英语中的元音是**'a', 'e', 'i', 'o', 和'u'。**

注意: 这些元音不包括字母 "y"

限制条件
1 <= s.length <= 3*105
s ,由可打印的ASCII字符组成。

例子

让我们来看看一些例子,以提高我们对这个问题的理解。

Example 1:
Input: s = "Eunoia"
Output: "ainouE"
Explanation: The string consists of all alphabets in English. So it is simply a case of reversing the entire string here.

Example 2:
Input: s = "Finxter"
Output: "Fenxtir"
Explanation: The vowels in this string are 'i' and 'e'. The position of these vowels have been swapped to display the output.

Example 3:
Input: s = "hellOO"
Output: "hOllOe"
Explanation: The position of vowels 'O' and 'e' have been swapped in this case.

Example 4:
Input: s = "python3.6"
Output: "python3.6"
Explanation: This string has no vowel. So it remains unchanged.

Example 5:
Input: s = "UAE"
Output: "EAU"
Explanation: The position of vowels 'U' and 'E' have been swapped in this case.

现在你对这个问题有了一个清晰的认识,让我们来深入了解一下解决方案。

方法1:使用Python列表作为堆栈

办法。由于问题要求你只反转元音,这种方法的想法是使用Python列表作为堆栈数据结构,把元音放在堆栈中。通过这样做,你可以在以后将包含最右边元音的栈顶替换为字符串左端的元音。

堆栈数据结构遵循**LIFO(Last In First Out)FILO(First In Last Out)**的方法来对其元素进行操作。你可以在Python中使用一个列表来实现堆栈的这个属性,以解决这个问题。

快速回顾。 list.pop() 方法删除并返回现有list 中的最后一个元素。带有可选的参数indexlist.pop(index) 方法删除并返回位置在index 的元素。

相关文章。Python 列表 pop()

算法

  1. 首先,将英语字母的所有元音存储在一个单独的列表中,同时创建另一个空列表。
  2. 在第一次迭代中,对于字符串中的每个字符,如果该字符存在于包含所有元音的列表中,则将其追加到空栈中。
  3. 如果该字符不存在于包含元音的列表中,则将其添加到新的字符串中,否则将堆栈顶部的字符添加到下一个字符串中。
  4. 最后,返回新的字符串。

让我们以代码的形式来实现这个算法。

def rev_vowels(s):
    vow = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
    st = []
    new_s = ''
    for v in s:
        if v in vow:
            st.append(v)
    for v in s:
        if v in vow:
            new_s = new_s + st.pop()
        else:
            new_s = new_s + v
    return new_s

让我们在我们的例子上运行这段代码,检查它是否有效。

# Example 1
s = "Eunonia"
print(rev_vowels(s))
# ainouE

# Example 2
s = "Finxter"
print(rev_vowels(s))
# Fenxtir

# Example 3
s = "hellOO"
print(rev_vowels(s))
# hOllOe

# Example 4
s = "python3.6"
print(rev_vowels(s))
# python3.6

# Example 5
s = "UAE"
print(rev_vowels(s))
# EAU

是的!它通过了所有的测试案例。

复杂度分析

  • 时间复杂度。由于你必须遍历字符串两次,这个方法的时间复杂性将是O(n) + O(n) = O(2n) ~ O(n)
  • 空间复杂度:在最坏的情况下,字符串中的所有字符都是元音。(参考例子5)在这种情况下,列表将包含所有的字符,因此空间复杂度将是O(n)

讨论。在这个方法中,我们在每种情况下都遍历了整个数组。虽然我们知道只有当数字是9的时候,我们才需要更新携带的数字,否则就保持0。所以,有没有一种可能的解决方案,我们可以在原始数组中更新数值,而不需要创建一个全新的数组?这将是一个更好的解决方案,因为我们可以在数字小于9的时候终止这个过程。

方法2:使用两个指针

方法。另一种处理这个问题的方法是在给定字符串的开始和结束处使用两个指针**(i和j**)。你必须检查该字符是否是元音。如果是,你必须在起点和终点指针的帮助下,将这两个值互相交换。

现在让我们来看看这个算法。

**注意:**由于Python字符串是不可改变的,你不能直接交换字符。你必须创建一个列表(Python 列表是可变的)来支持交换。在返回这个列表时,你可以使用 join 函数。

算法。

  1. 初始化两个变量i = 0j = length(s)-1 ,它们将指向字符串的开始和结束。因此,ij 代表这里的两个指针。
  2. i 小于j ,运行一个循环,检查当前字符是否是元音。
  3. 在这个循环中,你必须再执行两个循环,将指针移到元音上,使其指向元音。
  4. 交换由ij 指向的值。为了继续检查字符串中的元音,然后在指针的帮助下交换它们,将指针i 向右移动,同时将指针 j 向左移动。
  5. 最后,返回新的字符串。

让我们用Python代码来实现这个算法。

def rev_vowels(s):
    vow = ['a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U']
    new_s = list(s)
    i, j = 0, len(s) - 1
    while i <= j:
        while i < j and s[i] not in vow:
            i = i + 1
        while i < j and s[j] not in vow:
            j = j - 1
        if i > j:
            break
        new_s[i], new_s[j] = new_s[j], new_s[i]
        i = i + 1
        j = j - 1
    return ''.join(new_s)

让我们在我们的测试案例上试试这个。

# Example 1
s = "Eunonia"
print(rev_vowels(s))
# ainouE

# Example 2
s = "Finxter"
print(rev_vowels(s))
# Fenxtir

# Example 3
s = "hellOO"
print(rev_vowels(s))
# hOllOe

# Example 4
s = "python3.6"
print(rev_vowels(s))
# python3.6

# Example 5
s = "UAE"
print(rev_vowels(s))
# EAU

好哇!它通过了所有的测试案例。

复杂度分析

  • 时间复杂度:在这种方法中,字符串只被遍历一次。因此,时间复杂性为O(n)。
  • 空间复杂度。这种方法的空间复杂度将是O(n),因为我们必须创建一个列表(Python字符串是不可变的)来存储字符串字符,以便交换值。

方法3:使用正则表达式

没有多少程序员对Python正则表达式非常熟悉。但是一旦你掌握了使用正则表达式模块的艺术,它就会使你成为一个极其强大的工具,轻松地解决复杂的问题。

A 快速 回顾一下。

re.findall() Visual Explanation

在这里阅读更多信息:"Python re.findall() - 你需要知道的一切"

现在让我们看一下,你如何使用正则表达式来解决这个问题。

import re


def rev_vowels(s):
    vowels = re.findall('(?i)[aeiou]', s)
    return re.sub('(?i)[aeiou]', lambda m: vowels.pop(), s)

测试案例分析。

# Example 1
s = "Eunonia"
print(rev_vowels(s))
# ainouE

# Example 2
s = "Finxter"
print(rev_vowels(s))
# Fenxtir

# Example 3
s = "hellOO"
print(rev_vowels(s))
# hOllOe

# Example 4
s = "python3.6"
print(rev_vowels(s))
# python3.6

# Example 5
s = "UAE"
print(rev_vowels(s))
# EAU

你也可以用一句话来解决这个问题,如下图所示(可能不是在面试时想出的最聪明的主意😬 )。

import re


def rev_vowels(s):
    return re.sub('(?i)[aeiou]', lambda m, v=re.findall('(?i)[aeiou]', s): v.pop(), s)

谷歌、Facebook和亚马逊的工程师都是正则表达式大师。如果你也想成为这样的人,请看看我们的新书。 学习Python Regex的最聪明方法 (Amazon Kindle/Print, opens in new tab)

结论

我希望你喜欢这个编码面试问题。请**继续关注订阅**更多有趣的编码问题。

🎓 帖子积分。 Shubham Sayon和Rashi Agarwal


推荐。Finxter计算机科学学院

  • 在Fiverr和Upwork上最抢手的技能之一就是网络刮削。请不要搞错。_以编程方式从网站中提取数据_在当今这个由网络和远程工作塑造的世界上,网络刮削是一项重要的生活技能。
  • 那么,你想掌握使用Python的BeautifulSoup进行网络搜刮的艺术吗?
  • 如果答案是肯定的--本课程将带领你从网络刮削的初学者变成专家。

现在就**加入BeautifulSoup的网络刮削大师班**,明天就能掌握它!

The post[Google Interview] Reverse Vowels in a String In Pythonfirst appeared onFinxter.