Leetcode 原题链接
解法一
这道题很简单,令双指针 l l l 和 r r r 从两侧相向移动,交换元音字母即可。但大多人的实现是如下这种可简化的嵌套循环。
如果是 Java 等 String 不可变的语言,应先转换为 CharArray,交换完元音字母后改回 String 形式。
此处仅提供 Java 代码,多语言代码块可以看这里。
class Solution {public String reverseVowels(String s) {int l = 0; // 左指针int r = s.length() - 1; // 右指针// 将字符串 s 改成数组,方便交换字符char[] chars = s.toCharArray();// 所有元音字母,hash set 形式Set<Character> vowels = new HashSet<>(Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'));while (l < r) {// 从左向右找元音字母while (l < s.length() && !vowels.contains(chars[l])) l++;// 从右向左找元音字母while (r >= 0 && !vowels.contains(chars[r])) r--;// 双指针相遇,退出if (l >= r) break;// 交换char temp = chars[l];chars[l++] = chars[r];chars[r--] = temp;}return new String(chars);}
}
解法二
我们可以在一个循环中直接实现。
class Solution {public String reverseVowels(String s) {int l = 0;int r = s.length() - 1;char[] chars = s.toCharArray();Set<Character> vowels = new HashSet<>(Arrays.asList('a', 'e', 'i', 'o', 'u', 'A', 'E', 'I', 'O', 'U'));while (l < r) {if (!vowels.contains(chars[l])) {l++;} else if (!vowels.contains(chars[r])) {r--;} else {char temp = chars[l];chars[l] = chars[r];chars[r] = temp;l++;r--;}}return new String(chars);}
}
这种简化循环的技巧在实际开发中也能用到,只是稍慢于传统的嵌套 while
循环。
读者在初次接触时可能不太习惯,但一回生,二回熟。
复杂度
时间: Θ ( n ) \Theta(n) Θ(n)
空间:
- 在 C++ 等 String 可变的语言中为 Θ ( 1 ) \Theta(1) Θ(1)
- 在其他语言中因为构建了数组,为 Θ ( n ) \Theta(n) Θ(n)
推广
以下均为个人所著,兼顾了面试、本科、硕士阶段,包含清晰的 PPT 动画展示以及配套的练习题。读者也在陆续写其他算法教程。
-
附个人题解的双指针题单
-
图论入门
-
图论进阶