持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情.
反转字符串
题目描述
编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。
不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用 O(1) 的额外空间解决这一问题。
示例 1:
输入: s = ["h","e","l","l","o"]
输出: ["o","l","l","e","h"]
示例 2:
输入: s = ["H","a","n","n","a","h"]
输出: ["h","a","n","n","a","H"]
解题思路
思路一: 双指针
头尾双指针指向元素不断迭代交换
解法如下:
- 将 left 指向字符数组首元素,right 指向字符数组尾元素。
- 当 left < right:
- 交换 s[left] 和 s[right];
- left 指针右移一位,即 left = left + 1;
- right 指针左移一位,即 right = right - 1。
- 当 left >= right,反转结束,返回字符数组即可
实现代码如下:
/**
* @param {character[]} s
* @return {void} Do not return anything, modify s in-place instead.
*/
var reverseString = function(s) {
let len = s.length;
for (let left = 0 , right = len - 1; left < right; ++left, --right) {
let tmp = s[left];
s[left] = s[right];
s[right] = tmp;
}
};
时间复杂度:O(N),其中 N 为字符数组的长度。因为是使用了双指针,所以一共执行了 N/2 次的交换。 空间复杂度:O(1)。只使用了常数空间
或者不使用临时变量,使用ES6语法中交换两个变量的值:
for (let left = 0, right = n - 1; left < right; ++left, --right) {
[s[left], s[right]] = [s[right], s[left]];
}
思路二: 递归解决
- 向内递归
- 直至头尾指针相等时返回, 即从内向外开始交换元素 继而达到反转字符串效果
实现代码如下:
/**
* @param {character[]} s
* @return {void} Do not return anything, modify s in-place instead.
*/
var reverseString = function(s) {
let len = s.length;
const recursion = function(s, left, right) {
if (left >= right) // 直至头尾指针相等时返回
return;
// 即从内向外开始交换元素 继而达到反转字符串效果
recursion(s, left + 1, right - 1);
// 交换
[s[left], s[right]] = [s[right], s[left]]
}
recursion(s, 0, len - 1);
};