• 移动零(力扣热题HOT100 之 力扣283)java


    目录

    一、题目描述

    二、思路讲解

    三、Java代码实现

    三、代码优化


    一、题目描述

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

    请注意 ,必须在不复制数组的情况下原地对数组进行操作。

    示例 1:

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


    示例 2:

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

    提示:

    1 <= nums.length <= 104
    -231 <= nums[i] <= 231 - 1
     

    进阶:你能尽量减少完成的操作次数吗?

    二、思路讲解

            我们可以统计一下nums各个位置前面分别有多少0,有n个0就把这个位置上的数向前移动n位 ,再把数组末尾空缺的位置补上0即可。

    三、Java代码实现

    1. class Solution {
    2. public void moveZeroes(int[] nums) {
    3. int len = nums.length;
    4. int []ling = new int[len]; //记录第i位前面有几个0
    5. int sum = 0; //记录一共有几个0
    6. //记录第i位前面有几个0
    7. for(int i=0; i<len; i++){
    8. if(nums[i] == 0){
    9. ling[i] = -1;
    10. sum++;
    11. } else {
    12. ling[i] = sum;
    13. }
    14. }
    15. //前面有几个0就向前移动几位
    16. for(int i=0; i<len; i++){
    17. if(nums[i] != 0){
    18. nums[i-ling[i]] = nums[i];
    19. }
    20. }
    21. //把后面补上0
    22. for(int i=len-1; i>=len-sum; i--){
    23. nums[i] = 0;
    24. }
    25. }
    26. }

            时间复杂度:        O(N)

            空间复杂度:        O(N)

    三、代码优化

            时间复杂度已经足够优秀了,但是操作次数过多;空间复杂度还不够完美,能否减少空间的使用呢?

            这就需要用到双指针了。

            1、开始时两指针同时在最左边,然后左右指针同时右移去找零。

            2、当左指针指零时,右指针右移去找非零。

            3、当找到非零时,交换;

            4、左右指针再同时右移去找零(重复1,2,3直到右指针达到末尾)

    1. class Solution {
    2. public void moveZeroes(int[] nums) {
    3. int n = nums.length, left = 0, right = 0;
    4. while (right<n) {
    5. //如果左指针指非零,无需交换,双指针后移
    6. while(right<n && nums[left]!=0){
    7. left++;
    8. right++;
    9. }
    10. //如果左指针指零,那么右指针后移去找非零,然后交换
    11. while(right<n && nums[right]==0){
    12. right++;
    13. }
    14. if(right<n){
    15. swap(nums, left, right);
    16. //交换完之后,双指针后移一位
    17. left++;
    18. right++;
    19. }
    20. }
    21. }
    22. public void swap(int[] nums, int left, int right) {
    23. int temp = nums[left];
    24. nums[left] = nums[right];
    25. nums[right] = temp;
    26. }
    27. }

            可以简化一下代码: 

    1. class Solution {
    2. public void moveZeroes(int[] nums) {
    3. int n = nums.length, left = 0, right = 0;
    4. while (right < n) {
    5. if (nums[right] != 0) {
    6. swap(nums, left, right);
    7. left++;
    8. }
    9. right++;
    10. }
    11. }
    12. //交换
    13. public void swap(int[] nums, int left, int right) {
    14. int temp = nums[left];
    15. nums[left] = nums[right];
    16. nums[right] = temp;
    17. }
    18. }

            时间复杂度:        O(N)

            空间复杂度:        O(1)

  • 相关阅读:
    TairSearch:加速多列索引查询
    Could not find a version that satisfies the requirement tb-nightly
    screenfull全屏、退出全屏、指定元素全屏的使用步骤
    Apache Httpd 常见漏洞解析(全)
    uniapp组件库总结笔记
    深入解读Java SPI,还有谁不会?
    python怎么给类属性赋值 python 类属性
    b 树和 b+树的理解
    一文让你掌握Vue的状态管理机Vuex
    【Maven教程】(八):使用 Nexus 创建私服 ~
  • 原文地址:https://blog.csdn.net/m0_49499183/article/details/125459418