为何反向遍历数组无法完成原地反转?需赋值原数组才生效?
原地反转字符串数组:为何返回新数组会出错?
问题背景
我正在做一道要求原地反转字符串数组的编程题,函数定义如下:
/** * @param {character[]} s * @return {void} Do not return anything, modify s in-place instead. */ var reverseString = function (s) { };
示例输入为["h","e","l","l","o"],需要输出["o","l","l","e","h"]。
错误的初始写法
我最初写的代码如下,但被判定为错误:
/** * @param {character[]} s * @return {void} Do not return anything, modify s in-place instead. */ var reverseString = function (s) { let arr = []; for (let i = s.length-1;i >= 0; i--){ arr.push(s[i]); } return arr; };
修改后的正确写法
调整后代码运行正常:
/** * @param {character[]} s * @return {void} Do not return anything, modify s in-place instead. */ var reverseString = function (s) { let reversed = []; for (let i = s.length - 1; i >= 0; i--) { reversed.push(s[i]); } for (let i = 0; i < s.length; i++) { s[i] = reversed[i]; } return reversed; };
我想请教:为何第一种写法不正确?为什么必须把反转后的元素赋值给原数组才能通过测试?
解答
核心原因在于题目明确要求原地修改原数组,这一点已经写在函数注释的@return说明里:Do not return anything, modify s in-place instead.
第一种写法的问题
- 你创建了一个新数组
arr,把原数组的元素倒序存入后返回,但原数组s的内容完全没有被修改,仍然保持初始状态。 - 评测系统的判定逻辑是检查你传入的原数组是否被反转,而不是读取你返回的新数组。所以即便你返回的数组是正确的,原数组没变化,就会被判定为错误。
- 你创建了一个新数组
第二种写法正确的原因
- 虽然你同样创建了临时数组
reversed,但关键步骤是通过第二个循环,把reversed里的元素逐个赋值给原数组s的对应位置。这一步直接修改了原数组s的内容,满足了“原地修改”的要求。 - 顺便提一句:最后
return reversed是多余的,因为题目要求返回void,不过这步不影响结果,只要原数组被正确修改就能通过测试。
- 虽然你同样创建了临时数组
更优的原地反转写法
其实不需要额外创建临时数组,用双指针法可以实现纯原地反转,空间复杂度为O(1):
var reverseString = function(s) { let left = 0; let right = s.length - 1; while (left < right) { // 交换左右指针位置的元素 [s[left], s[right]] = [s[right], s[left]]; left++; right--; } };
内容的提问来源于stack exchange,提问作者Gaurav Tak
相关产品推荐
相关产品推荐

