LeetCode 917:嵌套while循环版reverseOnlyLetters失效原因解析
问题解析:为什么嵌套while循环的reverseOnlyLettersNestedLoop无法正常工作
你的嵌套while循环版本会出现死循环或者错误交换的问题,核心原因是在内层循环移动指针时,没有及时检查left和right的边界关系,具体问题如下:
1. 死循环风险
当输入字符串全是非字母字符(比如"---"),或者剩余未处理的区域全是非字母时,内层while循环会无限制地移动指针:
- 外层循环进入时
left=0,right=2,满足left<right。 - 第一个内层while会持续执行
left++,因为initArr[left]始终是非字母(直到left超出数组范围,此时initArr[left]为undefined,正则测试依然返回false),导致left无限增大,陷入死循环。
2. 错误的交换操作
当某一侧的指针移动后与另一侧指针重合甚至超过时,代码依然会执行交换:
比如输入"a--":
- 外层循环进入后,左指针停在0(字母),右指针会一直自减到0(此时
left=right)。 - 代码依然会执行交换同一位置的字符(逻辑无意义),之后才移动指针退出循环,这属于不必要且错误的操作。
对比可正常运行的版本
if+continue的版本逻辑更严谨:
- 每次只移动一步指针,就立刻回到外层循环的
left<right判断,不满足条件直接退出,从根源避免了死循环。 - 只有当左右指针都指向字母时,才执行交换并同时移动两个指针,确保每一步操作都符合边界要求。
修正嵌套循环版本的方法
只需在内层while循环的条件中加入left < right的判断,并且在交换前再次确认指针边界:
var reverseOnlyLettersNestedLoop = function(s) { let initArr = s.split('') let left = 0 let right = initArr.length - 1 function isLetter(char) { return /^[a-zA-Z]$/.test(char); } while (left < right) { // 内层循环加入left < right判断,防止指针越界 while(left < right && isLetter(initArr[left]) === false) { left ++ } while(left < right && isLetter(initArr[right]) === false) { right-- } // 如果指针已经重合或交叉,直接退出 if(left >= right) break; // 执行交换 let temp = initArr[left] initArr[left] = initArr[right] initArr[right] = temp left++ right-- } return initArr.join('') };
内容的提问来源于stack exchange,提问作者Kevin Mei
相关产品推荐
相关产品推荐

