每日两题 双指针的应用,复写零,移动零

目录

1.移动零

1.1题目描述

1.2 题目解析

1.3 代码编写

2.复写零

2.1题目描述

2.2题目解析

2.3代码编写


1.移动零

1.1题目描述

  我们先来看题目描述,给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

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

1.2 题目解析

这道题的题目描述中,要求原地操作,那么我们可以使用双指针来操作这个题.

首先定义一个指针dest,和一个指针cur,让cur来遍历这个数组,如果遇到非0的,就和dest进行交换,直到cur遍历完这个数组即可.

第一步 定义两个指针 从左开始

第二步 cur往后走 遇到非0的元素就交换 交换以后dest在往右走.

直到全部遍历完即可.

1.3 代码编写

 public void moveZeroes(int[] nums) {
      int dest = 0;
      for(int cur = 0 ; cur<nums.length; cur++){
        if(nums[cur]!=0){
            int tmp = nums[cur];
            nums[cur] = nums[dest];
            nums[dest] = tmp;
            dest++;
        }
      }
}

2.复写零

2.1题目描述

   本题为: 给你一个长度固定的整数数组 arr ,请你将该数组中出现的每个零都复写一遍,并将其余的元素向右平移。

注意:请不要在超过该数组长度的位置写入元素。请对输入的数组 就地 进行上述修改,不要从函数返回任何东西。

2.2题目解析

 本题的意思很明显,就是遇到0了,写两遍,然后遇不到写一遍,直到把这个数组填充完即可.

如果不考虑那句就地修改就很简单,直接开辟另一个数组然后便利就能做完这道题,如果是竞赛不考虑复杂度的情况下,可以用这种暴力的解法来写,

我们按照题目要求,先考虑一下双指针能不能做到这道题,如果从前往后遍历的话, 如果遇到0了,那么后面的本来非0的元素也可能被覆盖掉,所以这种方法不可取

我们试试如果从后往前呢?

首先cur判断一下是不是0或者非0 如果非0 dest就复写一位 反之就两位,

我们发现从后往前貌似是可以的,

但是这里有一个问题,我们如何找到cur的位置呢?

我们可以通过双指针来先让dest走到数组的最后一个位置,然后就从后往前就行.

依旧是双指针,cur遇到非0,dest往后走一位,遇到0,dest往后走两位

走完大概是这个结果

注意 :如果最后是0,然后走两位越界了,就可能触发数组越界异常,所以我们得判断一下.

然后找到这两个位置以后,在使用从后往前的思路来走即可.

2.3代码编写

public void duplicateZeros(int[] arr) {
        int cur = 0, dest = -1, n = arr.length;
        while(cur<n){
            if(arr[cur]!=0)
                dest++;
            else {
                dest+=2;
            }
           
            if(dest>=n-1){
                break;
            }
             cur++;
           
        }
        if(dest==n){
            arr[n-1] = 0;
            dest-=2;
            cur--;
        }
        while(cur>=0){
            if(arr[cur]!=0){
                arr[dest--] = arr[cur];
            }else{
                arr[dest--] = 0;
                arr[dest--] = 0;
            }
            cur--;
        }
        

    }

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王尔政

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值