zoukankan      html  css  js  c++  java
  • 力扣283.移动零

     283. 移动零

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

    示例:

    输入: [0,1,0,3,12]
    输出: [1,3,12,0,0]
    说明:
    必须在原数组上操作,不能拷贝额外的数组。
    尽量减少操作次数。

     思路一:

    快慢指针遍历数组,把第0个非零数字移动到nums[0], 第一个非零数字移动到nums[1],第i个非零数字移动到nums[i]的位置

     1 class Solution {
     2     public void moveZeroes(int[] nums) {
     3         if(nums == null){
     4             return;
     5         }
     6 
     7         int noneZeroIndex = 0;
     8         int n = nums.length;
     9         for(int i = 0; i < n; i++){
    10             if(nums[i] != 0){
    11                 nums[noneZeroIndex++] = nums[i];
    12             }
    13         }
    14         // 把noneZeroIndex部分的所有元素都置为0
    15         Arrays.fill(nums, noneZeroIndex, n, 0);
    16     }
    17 }

    力扣测试时间为0ms, 空间为40.2MB

    复杂度分析:

    时间复杂度为O(n)

    空间复杂度为O(1)

    思路二:

    对上面的解法做了一点小改进,在判断nums[i]非零时,交换nums[i]和nums[noneZeroIndex]两个元素,而非仅仅给nums[noneZeroIndex]赋值,这样可以去除第二轮迭代。之所以选择交换而非直接给nums[i]赋值为0, 是因为,如果刚好i == noneZeroIndex, 那么将引发错误。

     1 class Solution {
     2     public void moveZeroes(int[] nums) {
     3         if(nums == null){
     4             return;
     5         }
     6 
     7         int noneZeroIndex = 0;
     8         int n = nums.length;
     9         for(int i = 0; i < n; i++){
    10             if(nums[i] != 0){
    11                 int temp = nums[noneZeroIndex]; // 交换noneZeroIndex和i的元素
    12                 nums[noneZeroIndex++] = nums[i];
    13                 nums[i] = temp;
    14             }
    15         }
    16     }
    17 }

    力扣测试时间为:0ms, 空间为:39.9MB

    复杂度分析:

    时间复杂度为O(n)

    空间复杂度为O(1)

    思路三:

    同样是快慢指针
    遍历数组,把当前0与下一个非0元素进行交换

     1 class Solution {
     2     public void moveZeroes(int[] nums) {
     3         if(nums == null){
     4             return;
     5         }
     6 
     7         // 遍历数组,把当前0与下一个非0元素进行交换
     8         int n = nums.length;
     9         int j= 0;
    10         for(int i = 0; i < n; i++){
    11             if(nums[i] == 0){
    12                 for(j = j + 1; j < n && nums[j] == 0; j++); // 查找下一个不为0的数字
    13                 if(j < n){  // 如果j < n, 交换nums[i] 和nums[j]
    14                     nums[i] = nums[j];
    15                     nums[j] = 0;
    16                 }else{
    17                     break;  // 如果j >= n,说明0已经全被移动到了末尾
    18                 }
    19             }else{
    20                 j++;
    21             }
    22 
    23         }
    24     }
    25 }

    力扣测试时间为0ms, 空间为:39.8MB

    复杂度分析:

    时间复杂度:i和j指针都只遍历了一次数组,所以时间复杂度为O(n),

    空间复杂度: 为O(1)

    思路参考:

    https://leetcode-cn.com/problems/move-zeroes/solution/yi-dong-ling-by-leetcode/

  • 相关阅读:
    【每天一道PAT】1001 A+B Format
    C++ STL总结
    开篇
    happen-before原则
    java多线程的状态转换以及基本操作
    集合初始容量
    fail-fast机制
    Stack
    Iterator
    Vector
  • 原文地址:https://www.cnblogs.com/hi3254014978/p/13110591.html
Copyright © 2011-2022 走看看