【LeetCode】双指针:同向快慢针

前言

今日练习目的:掌握两个指针通向遍历同一序列的解法,快针通常用于寻找目标,慢针用于记录写入位置

283:移动零

题目要求:给定一个数组,讲数组中为0的元素放在数组最后,同时保持非0元素的相对顺序

核心思路

定义一个快指针:快速遍历数组所有元素

一个慢指针:指向下一个非0元素应该存放的位置

具体流程:

fast从头扫描到尾

遇到非零元素:将其放在slow位置,slow++

最后slow之后的元素全部为0

代码实现

java 复制代码
int slow=0;
for(int fast=0;fast<nums.length;fast++){
if(nums[fast]!=0){
int temp=nums[fast];
nums[fast]=nums[slow];
nums[slow]=temp;
slow++;
}
}

总结

要有快慢指针思想:同一个数组中寻找元素

进阶写法:减少时间复杂度

把非0往前放,同时把0自动丢到后面

27:移动元素

题目要求:给你一个数组nums和一个值val

要求:原地删除所有等于val的元素,返回删除后数组的新长度

核心思路

与上一题类似

代码实现

java 复制代码
class Solution {
    public int removeElement(int[] nums, int val) {
       int slow=0;
       int n=nums.length;
       for(int fast=0;fast<n;fast++){
        if(nums[fast]!=val){
            int temp=nums[fast];
            nums[fast]=nums[slow];
            nums[slow]=temp;
            slow++;
        }
       }
       return slow;
    }
}

总结

与上一题同样的思路

直接return slow,slow即为新数组长度

26:删除有序数组中的重复项

题目要求:一个非严格递增排列的数组 nums,

要求:原地删除重复元素,并返回新数组长度

核心思考

对于原地删除重复元素,我们要想到用后续不重复元素去覆盖前一个重复元素。

代码实现

java 复制代码
class Solution {
    public int removeDuplicates(int[] nums) {
        int slow=0;
        for(int fast=1;fast<nums.length;fast++){
            if(nums[fast]!=nums[slow]){
                slow++;
                nums[slow]=nums[fast];
            }
        }
        return slow+1;
    }
}

本题进阶

如果题目给的数组元素顺序是完全无序的,我们应该想到HashSet 来去重

代码实现:

java 复制代码
HashSet<Integer> set=new HashSet<>();
int slow=0;
for(int fast=0;fast<nums.length;fast++){
if(!set.contains(nums[fast]){
set.add(nums[fast]);
nums[slow]=nums[fast];
slow++;
}
}
return slow;

总结

情况 方法
有序数组 双指针
无序数组 HashSet
无序 + 不允许额外空间 排序 + 双指针

19:删除链表的倒数第N个节点

题目要求:给定一个链表head和一个整数n:

要求:删除倒数第n个节点

返回删除后的链表头

核心思路

其实思路还是一样,只不过本题换成了链表,代表了以下几个地方有修改

  1. 需要先创建一个虚拟头节点,让fast/slow与链表接轨
  2. 链表的遍历方式不一样:走一步为fast=fast.next
  3. 删除节点:slow.next = slow.next.next;直接改变指针定位
  4. 返回值:dummy.next、

代码实现

java 复制代码
class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy = new ListNode(0);
        dummy.next = head;

        ListNode fast = dummy;
        ListNode slow = dummy;

        // fast先走n步
        for (int i = 0; i < n; i++) {
            fast = fast.next;
        }

        // 一起走
        while (fast.next != null) {
            fast = fast.next;
            slow = slow.next;
        }

        // 删除节点
        slow.next = slow.next.next;

        return dummy.next;
    }
}

总结

掌握链表的语法

详见核心思路

相关推荐
wsoz2 小时前
Leetcode普通数组-day5、6
c++·算法·leetcode·数组
啊哦呃咦唔鱼2 小时前
LeetCode hot100-105从前序与中序遍历序列构造二叉树
算法
favour_you___2 小时前
2026_4_8算法练习题
数据结构·c++·算法
汀、人工智能2 小时前
[特殊字符] 第57课:搜索旋转排序数组
数据结构·算法·数据库架构·图论·bfs·搜索旋转排序数组
倦王2 小时前
力扣日刷47
算法·leetcode·职场和发展
MicroTech20252 小时前
突破量子数据加载瓶颈,MLGO微算法科技推出面向大规模量子计算的分治态制备技术
科技·算法·量子计算
码王吴彦祖2 小时前
顶象 AC 纯算法迁移实战:从补环境到纯算的完整拆解
java·前端·算法
SccTsAxR2 小时前
算法基石:手撕离散化、递归与分治
c++·经验分享·笔记·算法
wuweijianlove2 小时前
算法测试中的数据规模与时间复杂度匹配的技术4
算法