LeetCode《初级算法》字符串之反转字符串 -- JavaScript

265 阅读1分钟

题目

题目链接:leetcode-cn.com/leetbook/re…

image.png


题解


1、首尾交换,向中间推进

题目很简单,要求空间复杂度为O(1); 使用两个下标 head 和 rear,初始时指向数组的开始和结束,互换数组中下标对应的两个值,然后两下标分别向中间推进一个位置(head++ ,rear--); 重复上面的步骤直到 rear < head ;

/**
 * @param {character[]} s
 * @return {void} Do not return anything, modify s in-place instead.
 */
var reverseString = function(s) {

    let temp = null;
    let head = 0,
        rear = s.length - 1;
        
    while(head < rear) {

        temp = s[head];
        s[head] = s[rear];
        s[rear] = temp;
        head++;
        rear--;
    } 
};


2、在上面方法的基础上改进

交换数组中首尾两数时不使用中间变量,改成使用位操作; 但是要注意不能直接对非数值字符进行位操作,因为对字符进行位操作时,会有如下问题:

js中为什么 'a'^'c' === 0 ?

因为两个字符参加位运算时会先使用 Number() 转换成 数值,而非数值字符通过 Number() 会被转换成 NaN ,而 NaN ^ NaN 的结果为 0 ;

因此对非字符进行位运算时要先转换成 Unicode 码后再进行位运算,位运算完成后再转换回去;


/**
 * @param {character[]} s
 * @return {void} Do not return anything, modify s in-place instead.
 */
var reverseString = function(s) {


    let head = 0,
        rear = s.length - 1;
        
    while(head < rear) {
        s[head] = s[head].charCodeAt();
        s[rear] = s[rear].charCodeAt();


        s[head] ^= s[rear];
        s[rear] ^= s[head];
        s[head] ^= s[rear];

        s[head] = String.fromCharCode(s[head]);
        s[rear] = String.fromCharCode(s[rear]);

        head++;
        rear--;
    } 
};

3、递归操作

由第一种方法可以知道,for 循环在不断的重复交换两个数组元素的操作,由此可以将其作为递归体,将算法改成递归的方式实现;

/**
 * @param {character[]} s
 * @return {void} Do not return anything, modify s in-place instead.
 */
var reverseString = function(s) {


    let head = 0,
        rear = s.length - 1;
        
    function reverse(arr,head,rear) {
        if(head < rear){
            let temp = arr[head];
            arr[head] = arr[rear];
            arr[rear] = temp;
            reverse(arr,head+1,rear-1);
        } 
    }

    reverse(s,0,s.length-1);

};

大家如果有更好的思路和解法,欢迎大家一起来讨论啊~

这是使用 JavaScript 对 LeetCode《初级算法》的每道题的总结和实现的其中一篇,汇总篇在这里:

juejin.cn/post/700669…