一、编程题: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; } }
总结
以上就是今天要讲的内容,一开始做题的时候,由思路受限,只能想到先用循环来进行解决,后面看到提示双指针,于是就开始尝试用双指针来解决,但由于逻辑理得不是很清,所以写出来的代码很冗余,不过最后还是通过了。就去看下别人的双指针,发现比我的很简洁,但思路差不多,于是在根据别人的代码对自己写的双指针进行优化,所以就赶紧记录一下这个方法,开阔一下思路。
感谢观看,如果有帮助到你,请给题解点个赞和收藏,让更多的人看到。🌹 🌹 🌹
也欢迎你,关注我。👍 👍 👍
原创不易,还希望各位大佬支持一下,你们的点赞、收藏和留言对我真的很重要!!!💕 💕 💕 最后,本文仍有许多不足之处,欢迎各位认真读完文章的小伙伴们随时私信交流、批评指正!