【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;
    }
}

总结

掌握链表的语法

详见核心思路

相关推荐
吃好睡好便好8 小时前
在Matlab中绘制横直方图
开发语言·学习·算法·matlab
仰泳之鹅9 小时前
【C语言】自定义数据类型2——联合体与枚举
c语言·开发语言·算法
x_yeyue11 小时前
三角形数
笔记·算法·数论·组合数学
念何架构之路12 小时前
Go语言加密算法
数据结构·算法·哈希算法
AI科技星12 小时前
《数学公理体系·第三部·数术几何》(2026 年版)
c语言·开发语言·线性代数·算法·矩阵·量子计算·agi
失去的青春---夕阳下的奔跑12 小时前
560. 和为 K 的子数组
数据结构·算法·leetcode
黎阳之光13 小时前
黎阳之光:以视频孪生重构智慧医院信息化,打造高标项目核心竞争力
大数据·人工智能·物联网·算法·数字孪生
丷丩13 小时前
三级缓存下MVT地图瓦片服务性能优化策略
算法·缓存·性能优化·gis·geoai-up
m0_6294947313 小时前
LeetCode 热题 100-----25.回文链表
数据结构·算法·leetcode·链表
ʚ希希ɞ ྀ14 小时前
单词拆分----dp
算法