【问题标题】:Program exits loop, can't understand why even with debugging程序退出循环,即使调试也不明白为什么
【发布时间】:2022-01-14 10:27:51
【问题描述】:

在示例 [0,0,1] 处失败,输出为 [0,1,0] 而不是 [1,0,0]。我在调试模式下浏览了代码,当p1变为0时,它跳出for循环,我不明白为什么,因为它应该再循环一次,然后递减到-1并退出循环.

给定一个整数数组 nums,将所有 0 移到它的末尾,同时保持非零元素的相对顺序。 请注意,您必须在不复制数组的情况下就地执行此操作。

示例 1:

输入:nums = [0,1,0,3,12] 输出:[1,3,12,0,0]

示例 2:

输入:nums = [0] 输出:[0]

package random.leetCode;

import java.util.Arrays;

public class MoveZeroes_TwoPointers_283 {
    public void moveZeroes(int[] nums) {
        int p2 = 0;
        int tempIndex = 0;
        int lastIndex = nums.length - 1;

        for (int p1 = nums.length - 1; p1>=0;  p1--)
        {
            if (nums[p1] == 0)
            {
                if (p1 == nums.length - 1 && nums.length == 1)
                {
                    break;
                }

                tempIndex = p1;
                p2 = p1 + 1;
                while (p2 <= lastIndex)
                {
                    int temp = nums[p1];
                    nums[p1] = nums[p2];
                    nums[p2] = temp;
                    p2 += 1;
                    p1 += 1;
                }
                p1 = tempIndex -1;
                lastIndex--;
            }
        }
    }

    public static void main(String[] args) {
        MoveZeroes_TwoPointers_283 example = new MoveZeroes_TwoPointers_283();
//       int[] numbersToBeSorted = new int[]{0,1,0,3,12,0,11,0,0};
//        int[] numbersToBeSorted = new int[]{0};
//        int[] numbersToBeSorted = new int[]{0,0};
//        int[] numbersToBeSorted = new int[]{1};
//        int[] numbersToBeSorted = new int[]{1,1};
       int[] numbersToBeSorted = new int[]{0,0,1};
        example.moveZeroes(numbersToBeSorted);
        System.out.println(Arrays.toString(numbersToBeSorted));
    }
}```

【问题讨论】:

    标签: java for-loop pointers data-structures


    【解决方案1】:
    for (int p1 = nums.length - 1; p1>=0;  p1--) {
    ...
        tempIndex = p1;
    ...
        p1 = tempIndex -1;
    }
    

    您在此循环中将 p1 递减两次。你可能不是故意的。

    【讨论】:

    • 该减量的目的是将 p1 返回到最后找到的 0 的前一个位置,以便它可以重新开始向后搜索下一个 0。在这一点上消除递减实际上返回相同的数组 [1,0,0]
    • @Art 如果我把它改成p1 = tempIndex;(没有-1)我得到[1,0,0],这是预期的结果。如果您看到一些代码行为异常的输入,则可能存在更多问题。
    • 你是对的!我把事情搞混了,把正确的结果误解为不正确。确实,根据您的建议,算法通过了。谢谢!
    【解决方案2】:

    有趣。我认为问题在于当您找到两个连续的零并管理这些指针时。让我知道你对这个算法的看法。

    void main() {
        int[] input = new int[]{0,0,1};
        
        // whenever finds a zero, move it to the end
        for (int i=0; i < input.length; i++) {
           if (input[i] == 0) moveToEnd(i, input);
        }
    
        System.out.println(input);
    }
    
    // move to the end by swapping elements
    void moveToEnd(pos, arr) {
       for (int i = pos + 1; i < arr.length; i++) {
           int aux = arr[pos];
           arr[pos] = arr[i];
           arr[i] = aux;
           post = i;
       }
    }
    

    【讨论】:

    • 我更新了它以符合 leetcode 要求 public void moveZeroes(int[] nums) { // whenever finds a zero, move it to the end for (int i=0; i &lt; nums.length; i++) { if (nums[i] == 0) moveToEnd(i, nums); } // System.out.println(input); } // move to the end by swapping elements void moveToEnd(int pos, int[] arr) { for (int i=pos; i &lt; arr.length; i++) { int aux = arr[pos]; arr[pos] = arr[i]; arr[i] = aux; } } 并且在这个测试用例中失败:[0,1,0,3,12] - 输出 = [12,3,0,1,0 ]
    • 这是我能做的最好的编辑,对不起!
    • 嗯,很有趣。我还没有对它进行适当的测试,但想法就在那里,我想我可能在 moveToEnd 方法中有一个错误,但我认为它的逻辑是有效的。你觉得@Art 怎么样?更新:我修复了循环,我忘了保持 pos 更新!
    • 我已经跳过了这个问题,但你可以在这里查看:leetcode.com/problems/move-zeroes - 它有几十个测试用例,它会告诉你速度和内存
    猜你喜欢
    • 2016-03-12
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-03
    • 1970-01-01
    • 2019-06-10
    • 1970-01-01
    相关资源
    最近更新 更多