题目描述
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 char[] 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
你可以假设数组中的所有字符都是 ASCII 码表中的可打印字符。
示例 1:
输入:[“h”,”e”,”l”,”l”,”o”]
输出:[“o”,”l”,”l”,”e”,”h”]
示例 2:
输入:[“H”,”a”,”n”,”n”,”a”,”h”]
输出:[“h”,”a”,”n”,”n”,”a”,”H”]
题解
如果不考虑题目条件,可以考虑使用 StringBuilder 的 reverse() 反转方法。
class Solution {
public void reverseString(char[] s) {
StringBuilder builder = new StringBuilder(String.valueOf(s));
s = builder.reverse().toString().toCharArray();
}
}
根据题目要求:不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间
思路 - 对称交换
直接将字符数组第一个与最后一个互换位置,第二个与倒数第二个互换位置即可。
class Solution {
public void reverseString(char[] s) {
int length = s.length;
for (int i = 0; i < length / 2; i++) {
char temp = s[i];
s[i] = s[length - 1 -i];
s[length - 1 - i] = temp;
}
}
}
双指针思想
对于长度为 N 的待被反转的字符数组,我们可以观察反转前后下标的变化,
- 反转前字符数组为 s[0] s[1] s[2] … s[N - 1];
- 反转后字符数组为 s[N - 1] s[N - 2] … s[0];
- 比较反转前后下标变化很容易得出 s[i] 的字符与 s[N - 1 - i] 的字符发生了交换的规律,因此我们可以得出如下双指针的解法:
- 定义两个变量left,right分别指向第一个元素和最后一个元素;
- 当 left < right 时,交换 left、right 指向的元素,同时 left 右移,right 左移;
当 left >= right 时,反转完成;
class Solution {
public void reverseString(char[] s) {
int length = s.length;
for (int left = 0, right = length - 1; left < right; left ++, right --) {
char temp = s[left];
s[left] = s[right];
s[right] = temp;
}
}
}
递归思想
class Solution {
public void reverseString(char[] s) {
if (s == null || s.length == 0)
return;
reverseSubChar(s, 0, s.length - 1);
}
public void reverseSubChar(char[] s, int left, int right) {
if (left >= right) {
return;
}
s[left] ^= s[right];
s[right] ^= s[left];
s[left] ^= s[right];
reverseSubChar(s, ++left, --right);
}
或者先递归再交换。
这里递归方法使用的 left + 1,而不是 ++left,原因是,left + 1 不会改变 left 的值,在递归结束返回时,交换 left 和 right 的下标才正确。public void reverseSubChar(char[] s, int left, int right) { if (left >= right) { return; } reverseSubChar(s, left + 1, right - 1); s[left] ^= s[right]; s[right] ^= s[left]; s[left] ^= s[right]; }
知识点:交换的几种方式
临时变量法
public void swap(int a, int b) { int temp = a; a = b; b = temp; }
运算法
使用 +、-、*、/、位运算等操作进行交换
public void swap(int a, int b) { a = a + b; b = a - b; a = a - b; }
public void swap(int a, int b) { a = a - b; b = a + b; a = b - a; }
public void swap(int a, int b) { a ^= b; b ^= a; a ^= b; }