LeetCode刷题---283. 移动零(双指针)

请添加图片描述

  • 所属专栏:【LeetCode题解(持续更新中)】

  • 作  者:我是夜阑的狗

  • 个人简介:一个正在努力学技术的码仔,专注基础和实战分享 ,欢迎咨询!

  • 欢迎大家:这里是CSDN,我总结知识的地方,喜欢的话请三连,有问题请私信

您的点赞、关注、收藏、评论,是对我最大的激励和支持!!!

文章目录

  • 前言
  • 一、编程题:876. 链表的中间结点(双指针思路)
      • 1.题目描述
      • 2.示例1:
      • 3.输出描述:
      • 4.提示:
  • 二、解题思路
      • 1.思路
  • 三、代码实现
  • 总结


前言

  大家好,又见面了,我是夜阑的狗,本文是专栏【LeetCode题解】专栏的第3篇文章,主要讲解是LeetCode283. 移动零(双指针)。
  专栏地址:【LeetCode题解(持续更新中)】, 此专栏是我是夜阑的狗对LeetCode问题的讲解,希望能够加深自己的印象,以及帮助到其他的小伙伴。
  如果文章有什么需要改进的地方还请大佬不吝赐教。


一、编程题:876. 链表的中间结点(双指针思路)

1.题目描述

  给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。请注意 ,必须在不复制数组的情况下原地对数组进行操作。 LeetCode题目链接

2.示例1:

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

3.输出描述:

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

4.提示:

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

二、解题思路

1.思路

解决方法1(个人想法):

  • Step1.创建两个指针left,right,其中left赋值为-1;right赋值为0,left指针用于指向0的位置,rigtht指针指向非0的位置;
  • Step2.用for循序遍历整个数据,当当前数据为0且长度不为1的时候,就给left指针赋值;
  • Step3.在给left指针赋值时,也需要进行判定left当前位置是否大于要赋值的位置,且left不等于-1;
  • Step4.当数据不等于0且left指针不等于-1,就对数据进行交换;
  • Step5.交换完数据之后,需要对left指针进行处理,当left指针下一个指针上的值为0时,left+=1即可,反之left等于right;
    算法过程:
    LeetCode刷题---283. 移动零(双指针)_第1张图片
    根据前面的个人想法,可以对其进一步的优化
    解决方法2(优化双指针):
  • Step1.创建两个指针left,right,其中left,right赋值为0,left指针用于指向0的位置,rigtht指针指向非0的位置;
  • Step2.用for循序遍历整个数据,当当前数据为0的时候,就交换数据,并给left指针赋值;
    算法过程:其算法过程与前面相同,唯一的区别就是left一开始就指向0,而不是-1.

三、代码实现

这个代码是自己一步步试错试出来,整体代码逻辑上会有些冗余,不够简洁。每个代码块都写了注释,方便理解,代码还可以改进;
代码如下(示例):
解法一:

class Solution {
    public void moveZeroes(int[] nums) {
        int zerothis = -1;
        for(int i = 0; i < nums.length; i++){
            if(nums[i] == 0 && (i+1) != nums.length){
                 if(zerothis > i || zerothis == -1){
                    zerothis = i;
                 }
            }else if(nums[i] != 0 && zerothis != -1){
                nums[zerothis] = nums[i];
                nums[i] = 0;
                if(nums[zerothis+1] == 0){
                    zerothis += 1;
                }else{
                    zerothis = i;
                }
            }
        }
    }
}

解法二:

class Solution {
    public void moveZeroes(int[] nums) {
    	//当数组长度为1的时候,不用进行交换,直接返回
        if(nums.length == 1) return;
        int zerothis = 0;
        for(int i = 0; i < nums.length; i++){
            if(nums[i] != 0){
                swap(nums, zerothis, i);
                zerothis++;
            }
        }
    }
	//交换函数
    public void swap(int[] nums, int left, int right) {
        // System.out.println("nums[left] = " + nums[left] + " nums[right] = " + nums[right]);
        if(left == right) return;
        int temp = nums[left];
        nums[left] = nums[right];
        nums[right] = temp;
    }
}

总结

以上就是今天要讲的内容,一开始做题的时候,由思路受限,只能想到先用循环来进行解决,后面看到提示双指针,于是就开始尝试用双指针来解决,但由于逻辑理得不是很清,所以写出来的代码很冗余,不过最后还是通过了。就去看下别人的双指针,发现比我的很简洁,但思路差不多,于是在根据别人的代码对自己写的双指针进行优化,所以就赶紧记录一下这个方法,开阔一下思路。

感谢观看,如果有帮助到你,请给题解点个赞和收藏,让更多的人看到。

也欢迎你,关注我。

原创不易,还希望各位大佬支持一下,你们的点赞、收藏和留言对我真的很重要!!! 最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!

更多专栏订阅:

  • LeetCode题解(持续更新中)
  • Java Web项目构建过程
  • 数字图像处理
  • JavaScript随手笔记
  • 大数据学习笔记(华为云)
  • 程序错误解决方法(建议收藏)
  • 软件安装教程



订阅更多,你们将会看到更多的优质内容!!

你可能感兴趣的:(#,LeetCode,数组篇,leetcode,算法,链表,java,数据结构)