【算法刷题】Day7

文章目录

  • 283. 移动零
  • 1089. 复写零

283. 移动零

【算法刷题】Day7_第1张图片
原题链接

看到题目,首先看一下题干的要求,是在原数组内进行操作,平切保持非零元素的相对顺序

这个时候我们看到了示例一:
[ 0, 1, 0, 3,12 ]
这个时候输出成为了
[ 1, 3, 12, 0, 0 ]

我们这里可以运用**“双指针”**的方法这里的双指针,并不是 c 语言中的指针,而是用数组模拟的指针

首先:
我们要定义两个“指针”,cur 和 dest
cur:从左往右扫描数组,遍历数组
dest:已处理的区间内,在非零元素的最后一个位置

这个时候,数组就被 cur 和 dest 分成了三个区间
[ 0, dest ] 存放非零元素
[ dest+1, cur-1 ] 0元素
[ cur, n-1 ] 未处理的元素

然后:
cur 从前往后遍历
遇到 0 元素:cur++
遇到非零元素:swap(dest+1,cur); dest++; cur++;

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

【算法刷题】Day7_第2张图片

1089. 复写零

【算法刷题】Day7_第3张图片
原题链接

首先先看题干,把数组中每个零都复写一遍,其他元素水平右移,并且就地修改
这里我们需要用到双指针,从后往前进行复写

但是这里我们需要先遍历一遍,找到要复写的数字

方法:

  1. 定义cur 和 dest
    cur:遍历数组
    dest:目标的位置
  2. 先用双指针找到要复写的数字
    遇到 0,dest += 2;
    这里会遇到复写两个0,但是最后一个0超出数组范围
    这个时候我们需要把数组最后一个位置置为0,dest 的位置-2,cur–
  3. 从后往前遍历
public void duplicateZeros(int[] arr) {
        int cur = 0;
        int dest = -1;
        int n = arr.length;
        //1、找到最后一个需要复写的数
        while (cur < n) {
            if (arr[cur] == 0) {
                dest += 2;
            }else {
                dest += 1;
            }
            if (dest >= n-1) {
                break;
            }
            cur++;
        }
        //2、处理边界情况
        if (dest == n) {
            arr[n - 1] = 0;
            cur--;
            dest -= 2;
        }
        //3、从后向前完成复写操作
        while (cur >= 0) {
            if(arr[cur] != 0) {
                arr[dest--] = arr[cur--];
            }else {
                arr[dest--] = 0;
                arr[dest--] = 0;
                cur--;
            }
        }
    }

【算法刷题】Day7_第4张图片

你可能感兴趣的:(算法刷题,算法)