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

总结

掌握链表的语法

详见核心思路

相关推荐
CV-Climber32 分钟前
检索技术的实际应用
人工智能·算法
hhzz1 小时前
Tiger AI Platform平台中增加人脸识别功能
图像处理·人工智能·算法·计算机视觉·大模型
从零开始的代码生活_2 小时前
C++ 继承详解:访问控制、对象模型、菱形继承与设计取舍
开发语言·c++·后端·学习·算法
TsingtaoAI2 小时前
3D高斯泼溅技术发展及其在具身智能领域的应用综述
人工智能·算法·ai·具身智能·高斯泼溅
atunet2 小时前
关于图算法中的连通分量检测与最小割问题7
算法
心运软件3 小时前
银行客户流失预测(Python 完整实战)
算法
邪神与厨二病3 小时前
牛客周赛 Round 153
python·算法
qizayaoshuap5 小时前
# ❌ 井字棋 — 鸿蒙ArkTS Minimax AI算法与博弈系统设计
人工智能·算法·华为·harmonyos
皓月斯语6 小时前
B3842 [GESP202306 三级] 春游 题解
数据结构·c++·算法·题解
atunet6 小时前
树状结构在查询优化中的作用与实现细节7
算法