LeetCode 344 —字符串的反转
LeetCode 344 题意
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 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”]
作者:力扣 (LeetCode)
链接:https://leetcode-cn.com/leetbook/read/top-interview-questions-easy/xnhbqj/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
分析题意:
- 输入是一个字符数组 char [] s形式给出,输出也是通过char [] s形式给出;
- 方法的作用是将输入的字符数组反转过来;
- 不能给数组分配额外的空间,使用O(1)的空间复杂度
- 所有的字符都在ASCII码表中可以打印
Java全部解法
Solution 1
我们很容易想到通过一个中间数组对原来的数组进行反向赋值,定义一个字符数组 char [] t
对于第一个例子而言:
t0 = s4 = o
t1 = s3 = l
t2 = s2 = l
t3 = s1 = e
t4 = s0 = h
最后将字符数组t赋值给s,直接贴上代码
class Solution {
public void reverseString(char[] s) {
// 创建一个新的字符数组作为中间数组
char [] result = new char [s.length];
for (int i = 0; i < s.length ; i++) {
result[i] = s[s.length - 1 -i];
}
// 最后将这个数组赋值给原数组
for (int i = 0; i < s.length ; i++) {
s[i] = result[i];
}
}
}
这种解法不符合题意,有一个中间数组的开销,空间复杂度为O(N),不满足题意O(1)的额外空间。
Solution 2
有一种很常用的方法,双指针法,满足一定条件下,通过首尾两个指针指向元素交换位置即可实现两个元素交换,比较抽象,
h e l l o
头指针 start 指向h ,尾指针指向o ,当头指针不超过尾指针的时候,就不用交换了即为start >= end。
直接附上代码
class Solution {
public void reverseString(char[] s) {
// 定义首尾指针
int start = 0;
int end = s.length - 1;
while(start < end){
// 交换对应位置上的元素
char tmp = s[start];
s[start] = s[end];
s[end] = tmp;
start ++ ;
end --;
}
}
}
Solution 3
使用递归的方法,所有的循环都可以使用递归实现。递归分为两步
- 递归终止条件: start >= end
- 如何自己调用自己 :实现逻辑为两个对应的位置元素交换实现反转
附上代码
class Solution {
public void reverseString(char[] s) {
recursion(0,s.length - 1,s);
}
public static void recursion(int left, int right , char [] s){
// 递归条件
if (left >= right) return;
char tmp = s[left];
s[left] = s[right];
s[right] = tmp;
recursion(left + 1,right -1,s);
}
}
总结
- 双指针法是一种很常见的处理数组、链表、字符串、树等方法,涉及到元素比较的场合往往会用到此方法;
- 循环通常也可以用递归解决,递归需要找到终止条件和递归具体实现。