为什么Java实现moveZeroes函数更新条件时会出现无限循环?
问题原因分析
- 核心触发点出现在
i遍历到数组最后一个下标(值为nums.length - 1)时:
此时如果nums[i]为0,进入while循环调用shift方法。而shift方法中移位的循环条件是i < nums.length - 1,当入参index等于nums.length -1时,移位逻辑根本不会执行,只会执行最后一行nums[nums.length-1] = 0,也就是把原本就是0的最后一位再设为0。
方法返回后nums[i]的值仍然是0,while循环的判断条件始终成立,就会陷入无限调用shift的死循环。 - 补充说明:Java中数组是引用类型,就算
shift方法不返回数组,直接修改入参数组也会对原数组生效,你写的返回数组的操作属于冗余操作,不影响逻辑也不是死循环的诱因。
修复方案
方案1:最小改动适配原有逻辑
在while循环中增加边界判断,避免处理最后一位元素:
class Solution { public void moveZeroes(int[] nums) { for(int i=0;i<nums.length;i++){ // 最后一位是0不需要移位处理,直接跳过循环即可 while(i < nums.length -1 && nums[i]==0){ shift(i,nums); } } } public void shift(int index, int[]nums){ for(int i=index;i<nums.length-1;i++){ nums[i]=nums[i+1]; } nums[nums.length-1]=0; } }
方案2:优化为更高性能的双指针实现(时间复杂度O(n),原有实现时间复杂度为O(n²))
class Solution { public void moveZeroes(int[] nums) { // 慢指针指向最后一个非零元素应该存放的位置 int slow = 0; for (int fast = 0; fast < nums.length; fast++) { if (nums[fast] != 0) { int temp = nums[slow]; nums[slow] = nums[fast]; nums[fast] = temp; slow++; } } } }
内容的提问来源于stack exchange,提问作者user722214
相关产品推荐
相关产品推荐

