leetcode283.MoveZeroes 移动0

题目及分析

题目

给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:

输入: [0,1,0,3,12]
输出: [1,3,12,0,0]
说明:

必须在原数组上操作,不能拷贝额外的数组。
尽量减少操作次数。

分析

题目需要注意的地方:必须在原来的数组操作,说明限制空间复杂度限制为O(1)。
题目意思比较明确:将0移动到数组的末尾。但是不能有额外数组。所以单数组里面移动,可以使用交换的方式。
需要理解什么与什么进行交换。不仅仅是非0数字和0数字进行交换。交换的是将非0的数字通过交换进入了非0的区域里面。
所以需要定义的是非0的范围[0,nonZeroIndex),表示在[0,nonZeroIndex)左闭右开里面是非0数的范围。

结果示例

class Solution {
    public void moveZeroes(int[] nums) {
        int nonZeroIndex = 0;//[0,nonZeroIndex)为非0的范围
        for(int i=0;i<nums.length;i++){
            if(nums[i] !=0){
                swap(i,nonZeroIndex,nums);//交换非0数到非0范围里面。
                nonZeroIndex++;//非0区域扩大
            }
        }
    }
    private void swap(int a,int b,int[] nums){
        int temp = nums[a];
        nums[a] = nums[b];
        nums[b] = temp;
    }
}

特殊场景优化

这里可能的特殊场景为 nums数组里面全为非0的数字,这样每一次都是自己与自己进行交换操作。如果需要考虑这种极端场景的话,就需要加多一步判断。
     //考虑极端条件nums全部为非0时候,
     if(i != nonZeroIndex) {
           swap(i,nonZeroIndex,nums);//交换非0数到非0范围里面。
           nonZeroIndex++;//非0区域扩大
       }else{
            nonZeroIndex++;
       }

这样场景的代码为:

    class Solution {
    public void moveZeroes(int[] nums) {
        int nonZeroIndex = 0;//[0,nonZeroIndex)为非0的范围
        for(int i=0;i<nums.length;i++){
            if(nums[i] !=0){
                //考虑极端条件nums全部为非0时候
            	if(i != nonZeroIndex) {
            		swap(i,nonZeroIndex,nums);//交换非0数到非0范围里面。
                    nonZeroIndex++;//非0区域扩大
            	}else{
                    nonZeroIndex++;
                }
            }
        }
    }
    private void swap(int a,int b,int[] nums){
        int temp = nums[a];
        nums[a] = nums[b];
        nums[b] = temp;
    }
}
posted @ 2020-01-18 17:41  发包哥哥  阅读(109)  评论(0编辑  收藏  举报