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

发布于:2022-11-28 ⋅ 阅读:(639) ⋅ 点赞:(0)


一、编程题: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;
    算法过程:
    请添加图片描述
    根据前面的个人想法,可以对其进一步的优化
    解决方法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;
    }
}

总结

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

本文含有隐藏内容,请 开通VIP 后查看