将数组中的0全部移动到末尾

题目:Move Zeroes

描述:

Given an array nums, write a function to move all 0’s to the end of it while maintaining the relative order of the non-zero elements.
For example, given nums = [0, 1, 0, 3, 12], after calling your function, nums should be [1, 3, 12, 0, 0].
Note:
1、You must do this in-place without making a copy of the array.
2、Minimize the total number of operations.

翻译:

将数组中的所有0移动到末尾,并保持非0元素的顺序不改变。
比如[0,1,0,3,12]移动后的期望数组为[1,3,12,0,0]

小要求:

1、不能创建一个新的数组来做操作
2、尽量少的操作次数

答案:

public void moveZeroes(int[] nums) {
        int size = nums.length;
        int startIndex = 0;
// 0元素开始的位置
        int endIndex = 0;
// 0元素结束的位置
        int currentNum;
        int i= 0;
        // 第一步:找到第一个0元素开始的位置
        // 并将第一个0元素的游标赋值给startIndex&endIndex
        while(i < size){
            currentNum = nums[i];
            if (currentNum == 0) {
                startIndex = i;
                endIndex = i;
                break;
            }
            ++i;
        }
        // 如果当前数组中没有找到0元素,则推出
        if (nums[endIndex] != 0)
            return;

        // 将当前i的值加1;直接从刚才0元素位置的后一位置开始循环
        ++i;
        while (i < size) {
            currentNum = nums[i];
            if (currentNum == 0){//如果当前元素等于0,则将i值赋值给endIndex
                    endIndex = i;
            } else {
                // 如果不为0
                //则将当前元素赋值给nums[startIndex]
                // 并将当前位置的元素赋值为0
                // startIndex和endIndex都加1;
                nums[startIndex] = currentNum;
                nums[i] = 0;
                ++startIndex;
                ++endIndex;
            }
            ++i;
        }
    }

算法解释

此算法的精髓在于:在循环遍历中将0元素全部集中起来,整体向后移位,但是由于连续的0元素都是相等的,因此就算往前移位,也只需要将最前面的0元素和连续0元素的结束位置的后一位元素进行调换,相当于整个0元素块都向后移动了一位。
由于数组中可能有多个0,因此,第一次循环的时候,就将第一个0元素找出,并且记录当前0元素的游标(此时0元素开始的游标和结束的游标相等),第二次循环的时候,直接从0元素结束的游标的后一位开始循环遍历,如果循环遍历过程中,遇到了0元素,则将0元素的结束游标+1;如果没有遇到0元素,则将0元素开始位置和当前位置的数进行置换,并且将0元素的开始游标和结束游标都+1。

发布了54 篇原创文章 · 获赞 16 · 访问量 7万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章