LeeCode - 反转字符串

346 阅读2分钟

LeeCode - 反转字符串

题目:

编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 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"]

分析:

我第一时间想到的是array.prototype.reserve() ,但是题目要求原地修改数组、使用 O(1)的额外空间解决这个问题。但是我并不懂什么叫做:

  • 原地修改数组:因为缺乏数据结构的知识,所以对原地算法的概念还是很朦胧,这里暂认为原地修改等于不返回新数组,直接修改原数组,Array.prototype.reserve() 方法就是修改原数组。
  • O(1)的额外空间:计算过程中额外消耗的内存是固定值则是 O(1),如果需要额外内存正比于输入大小 n 的话则是 O(n)。

这里涉及了太多数据结构的概念与思想,故先 mark 一下,待后续系统学习后再来补充标准的方法。

答案:

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

结果:提交成功

耗时:176ms

内存:46.6MB

其他解法

双指针

双指针,交换头尾两个指针所指的两个位置的值,指针向中间移动一个位置,重复以上操作,直到两个指针交错

var serve = function(s){
  for(let i=0;i<s.length;i++){
    if(i<s.length-1-i){
       [s[i],s[s.length-1-i]]=[s[s.length-1-i],s[i]]
      console.log(s)   // 第一次:["o", "e", "l", "l", "h"]
      								 // 第二次:["o", "l", "l", "e", "h"]
    }
	}
	return s
}

结果:提交成功

耗时:188ms

内存:47.2MB

感觉这个方法比 Array.prototype.reverse()帅啊,直接交换数组首尾项的位置像中间收拢,等到i取得中间值后返回该数组。不知道数组的reverse()方法本质上是不是如此呢?有 dalao 来解答一下吗