LeetCode 283. 移动0

LeetCode官网题目地址:力扣

Java实现代码:

 package array;
 ​
 import java.util.ArrayList;
 import java.util.Arrays;
 ​
 /**
  * @ClassName LeetCode283
  * @Description 283. Move Zeroes: https://leetcode.com/problems/move-zeroes/description/
  * @Author Jiangnan Cui
  * @Date 2022/10/23 18:47
  * @Version 1.0
  */
 public class LeetCode283 {
     /**
      * @MethodName moveZeroes
      * @Description 方法1:新建一个数组,使用额外的空间存储元素
      *             时间复杂度: O(n)
      *             空间复杂度: O(n)
      *             但是不满足题目要求
      * @Author Jiangnan Cui
      * @Date 18:57 2022/10/23
      */
     public void moveZeroes(int[] nums){
         // 新建一个数组来保存有效元素,注意新建数组时必须对对数组进行初始化,指定数组长度,此处指定数组长度为nums.length,初始化元素全部为0
         int[] result = new int[nums.length];
         // 指定result数组起始下标,记录nums数组不为0元素
         int index = 0;
         // 遍历数组
         for (int i = 0; i < nums.length; i++) {
             // 将所有非0元素存到result数组中
             if(nums[i] != 0){
                 // 将不为0的元素添加到result数组中,同时index值加1
                 result[index++] = nums[i];
             }
             // 数组元素为0时,不作任何处理
         }
         // 注意此处不能直接使用nums = result,因为这样仅仅是引用地址的复制,方法调用后,引用指向消失,实际数组元素并未发生变化,还是原数组,要对数组元素逐一操作才可以
         // 参见:https://www.likecs.com/show-205118157.html
         // nums = result;
         // 将result中的所有元素依次放入到nums数组的位置,替换nums原有数组元素
         for (int i = 0; i < result.length; i++) {
             nums[i] = result[i];
         }
     }
 ​
     /**
      * @MethodName moveZeroes2
      * @Description 方法2:新建一个ArrayList,使用额外的空间来存储元素,相比数组而言,ArrayList初始化时不用直接指定长度,随着实际元素个数长度随之改变,可以节约空间
      *             时间复杂度: O(n)
      *             空间复杂度: O(n)
      *             但是不满足题目要求
      * @Author Jiangnan Cui
      * @Date 18:57 2022/10/23
      */
     public void moveZeroes2(int[] nums){
         // 用ArrayList来保存不为0的数组元素
         ArrayList<Integer> nonZeroElements = new ArrayList<Integer>();
         // 遍历数组
         for (int i = 0; i < nums.length; i++) {
             // 将所有非0元素存到nonZeroElements中
             if(nums[i] != 0){
                 nonZeroElements.add(nums[i]);
             }
         }
         // 将nonZeroElements中的所有元素依次放入到nums开始的位置
         for (int i = 0; i < nonZeroElements.size(); i++) {
             nums[i] = nonZeroElements.get(i);
         }
         // 将nums剩余的位置放置为0
         for (int i = nonZeroElements.size(); i < nums.length; i++) {
             nums[i] = 0;
         }
     }
 ​
     /**
      * @MethodName moveZeroes3
      * @Description 方法3:原地解决该问题,通过移动元素实现
      *              时间复杂度: O(n)
      *              空间复杂度: O(1)
      *              满足题目要求
      * @Author Jiangnan Cui
      * @Date 19:46 2022/10/23
      */
     public void moveZeroes3(int[] nums){
         // 定义存储不为0元素的起始下标,其中,数组中下标[0,...,index)的元素均为非0元素,[index,...,i]均为0
         int index = 0;
         // 遍历数组
         for(int i = 0; i < nums.length; i++){
             // 如果数组元素不为0
             if(nums[i] != 0){
                 // 将不为0的元素存储到原数组中指定满足要求的下标索引处,同时让index从0开始依次放入数组元素不为0的元素
                 nums[index++] = nums[i];
             }
             // 数组元素为0时,不做任何处理
         }
         // 遍历数组结束后,将nums剩余的位置赋值为0,起止位置为index
         for(int i = index; i<nums.length; i++){
             nums[i] = 0;
         }
     }
 ​
     /**
      * @MethodName moveZeroes4
      * @Description 方法4:方法3通过移动元素实现,最终还要补0,可通过交换数组元素实现
      *              时间复杂度: O(n)
      *              空间复杂度: O(1)
      *              满足题目要求
      * @Author Jiangnan Cui
      * @Date 19:49 2022/10/23
      */
     public void moveZeroes4(int[] nums){
         // 定义存储不为0元素的起始下标,其中,数组中下标[0,...,index)的元素均为非0元素,[index,...,i]均为0
         int index = 0;
         // 遍历数组
         for(int i = 0; i < nums.length; i++){
             // 如果数组元素不为0
             if(nums[i] != 0 ){
                 // 将指定位置的元素与不为0的元素进行交换,同时index大小加1,继续向右存储不为0的数组元素
                 swap(nums, index++, i);
             }
             // 数组元素为0时,不做任何处理
         }
         // 遍历数组结束后,数组满足题目要求
     }
 ​
     /**
      * @MethodName moveZeroes5
      * @Description 方法5:在方法4的基础上进行优化,避免自己和自己进行交换
      *              时间复杂度: O(n)
      *              空间复杂度: O(1)
      *              满足题目要求
      * @Author Jiangnan Cui
      * @Date 19:49 2022/10/23
      */
     public void moveZeroes5(int[] nums){
         // 定义存储不为0元素的起始下标,其中,数组中下标[0,...,index)的元素均为非0元素,[index,...,i]均为0
         int index = 0;
         // 遍历数组
         for(int i = 0; i < nums.length; i++){
             // 如果数组元素不为0
             if(nums[i] != 0 ){
                 // 将指定位置的元素与不为0的元素进行交换,同时index大小加1,继续向右存储不为0的数组元素
                 // 1.避免自己和自己交换,即指向同一个位置时,不交换
                 if(index == i){
                     // index加1右移,指定下一个满足要求的元素位置
                     index++;
                 }else{// 2.是两个位置时,进行交换,同时index加1右移,指定下一个满足要求的元素位置
                     swap(nums, index++, i);
                 }
             }
         }
         // 遍历数组结束后,数组满足题目要求
     }
 ​
     /**
      * @MethodName swap
      * @Description 进行数组中两元素的交换
      * @param: nums
      * @param: i
      * @param: j
      * @Author Jiangnan Cui
      * @Date 18:53 2022/10/23
      */
     private void swap(int[] nums,int i,int j) {
         int temp = nums[i];
         nums[i] = nums[j];
         nums[j] = temp;
     }
 ​
     public static void main(String[] args) {
         int[] arr = {0,1,0,3,12};
         (new LeetCode283()).moveZeroes(arr);
         System.out.println(Arrays.toString(arr));
         int[] arr2 = {0,1,0,3,12};
         (new LeetCode283()).moveZeroes2(arr2);
         System.out.println(Arrays.toString(arr2));
         int[] arr3 = {0,1,0,3,12};
         (new LeetCode283()).moveZeroes3(arr3);
         System.out.println(Arrays.toString(arr3));
         int[] arr4 = {0,1,0,3,12};
         (new LeetCode283()).moveZeroes4(arr4);
         System.out.println(Arrays.toString(arr4));
         int[] arr5 = {0,1,0,3,12};
         (new LeetCode283()).moveZeroes4(arr5);
         System.out.println(Arrays.toString(arr5));
     }
 }

输出结果:

 [1, 3, 12, 0, 0]
 [1, 3, 12, 0, 0]
 [1, 3, 12, 0, 0]
 [1, 3, 12, 0, 0]
 [1, 3, 12, 0, 0]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值