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

总结

掌握链表的语法

详见核心思路

相关推荐
江畔柳前堤6 小时前
大语言模型分布式训练:从并行策略到万卡工程的系统梳理
人工智能·分布式·深度学习·算法·目标检测·机器学习·语言模型
Forever Nore7 小时前
LeetCode 4 寻找两个正序数组的中位数 - 二分
算法·leetcode
罗西的思考8 小时前
【OpenClaw具身硬件】MiniClaw 阅读笔记---(1)基础
人工智能·算法·机器学习
蛋先生DX9 小时前
大模型参数存储格式揭秘:BF不是男朋友
深度学习·算法·llm
爱跳舞的烤冷面10 小时前
自学嵌入式第22天(数据结构——哈希)
数据结构·算法·哈希算法
猎嘤一号10 小时前
博弈论(Game Theory)的理论、算法与工程
人工智能·算法·安全·博弈论
月光船幽幽10 小时前
影子模式下保护 logits 不被修改
人工智能·python·算法
马拉AI10 小时前
腾讯开源 Agent 记忆系统,AI“换对话就忘”的问题有了新解法(附安装使用教程)
人工智能·算法·开源·科研
地平线开发者12 小时前
征程6工具链模型X86推理方式说明
算法
地平线开发者12 小时前
【征程6】校准量化中HistogramObserver解析
算法