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

总结

掌握链表的语法

详见核心思路

相关推荐
小蒋观天下34 分钟前
雷击与浪涌防护:前端SPD选型、接地网误区,接地不当反而引入干扰
深度学习·算法·机器学习
WBluuue2 小时前
数据结构与算法:分块(一):块状数组、块状链表
数据结构·c++·算法·链表
圣保罗的大教堂2 小时前
leetcode 3619. 总价值可以被 K 整除的岛屿数目 中等
leetcode
澳鹏Appen3 小时前
澳鹏重磅发布ExamOCRBench:面向端到端试卷判分的多任务基准
算法·benchmark·基准评测
benjormin3 小时前
Java数据结构 二叉搜索树
数据结构·算法
人工智能培训4 小时前
知识图谱:结构化表达实体与关系的知识组织技术
大数据·人工智能·算法·重构·生活·知识图谱
地平线开发者4 小时前
QAT 实战:从 PyTorch 模型到 J6E 实板精度与延时验证
pytorch·算法·自动驾驶
IT星宿4 小时前
github-gravity:用 Rapier2D 把 GitHub 贡献图做成 SVG 物理动画
算法·github
♡すぎ♡5 小时前
SWE 的基本条件
算法·swe·浅水模拟
郝学胜-神的一滴6 小时前
AI 编程智能体 17:四步搞定专属AI智能体
大数据·人工智能·python·神经网络·算法·langchain·强化学习