LeetCode 344:反转字符串

791 阅读1分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 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]];
} 

思路二: 递归解决

  1. 向内递归
  2. 直至头尾指针相等时返回, 即从内向外开始交换元素 继而达到反转字符串效果

实现代码如下:

/**
 * @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);

};

参考资料

LeetCode 344.反转字符串 - 力扣(LeetCode)