leetcode刷题技巧(一):双指针

一,双指针大概了解

双指针,指的是在遍历对象的过程中,不是普通的使用单个指针进行访问,而是使用两个相同方向(快慢指针)或者相反方向(对撞指针)的指针进行扫描,从而达到相应的目的。

1,快慢指针扫描过程中,一般有两种情况
1)快指针进行逐个扫描,慢指针依赖快指针进行更新,慢指针则作为一个记录变量辅助完成对快指针扫描到的元素的操作,或者说慢指针只是依赖于快指针单纯进行更新,等到循环的最后才会使用到更新完毕的慢指针的值。(即:快指针与慢指针之间有一个核心的关系,这个关系决定了慢指针如何更新)例如leetcode第206题:反转链表;leetcode第27题:移除元素
2)快指针扫描步长>慢指针扫描步长,从而达到一些目的
总之,快慢指针一般用于处理整个数组或者链表对象,最后使其形成新的对象。例如leetcode第142题:环形链表II

2,对撞指针适用于有序数组,一般用于从整个数组或者链表当中提取出符合条件的元组,即更加快速地提取出数组当中的数据。例如leetcode第15题:三数之和;leetcode第18题:四数之和;LeetCode第881题:救生艇
总结:双指针法充分使用了数组有序这一特征, 从而在某些情况下能够简化一些运算。

下面分别通过实践这些题目深入认识双指针算法。

二,快慢指针

2.1 leetcode第206题:反转链表;

2.1.1 题目:

给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
在这里插入图片描述

2.1.2 思路

观察这个链表,我们发现只需要让每一个节点的指针的next指向都改变为指向他的前节点,该链表就可以完成反转。我们可以使用O(n)的方法来解决这道题,使用双指针的思路。
1,其中now指针沿着链表依次遍历每一个元素,而per指针则记录now指针的上一个元素。
2,在每次循环遍历到某个元素的时候,只需要让now->next指向per,就完成了此处的链表反转,然后再让新的per=now,处理下一个元素。
3,需要注意的是,下一次循环处理的下一个节点不能通过now->next找到了,因为我们在处理过程中已经改变了now->next的指向,因此在本次处理now元素之前,首先要用临时变量存储now->next。方便我们进行下一次循环。

2.1.3 代码

(注意,题目中注释里面给的链表一个节点的样子,我们默认这个链表是不带头节点的)

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     ListNode *next;
 *     ListNode() : val(0), next(nullptr) {}
 *     ListNode(int x) : val(x), next(nullptr) {}
 *     ListNode(int x, ListNode *next) : val(x), next(next) {}
 * };
 */
class Solution {
   
public:
    ListNode* reverseList(ListNode* head) {
   
        ListNode* per=nullptr;
        ListNode* now=head;
        ListNode* tmp;
        while(now!=nullptr){
   
            tmp=now->next;
            now->next=per;
            per=now;
            now=tmp;
        }
        head=per;
        return head;
    }
};

2.1.4 总结

本题中使用到的双指针可以认为是快慢指针,其中快指针为now,而慢指针为per;快指针的目的是依次遍历链表元素,而慢指针记录了now->父亲的值,在本题中是为了辅助完成对now指针指向的元素的操作。

2.2 leetcode第27题:移除元素;

2.2.1 题目:

给你一个数组 nums 和一个值 val,你需要 原地 移除所有数值等于 val 的元素,并返回移除后数组的新长度。不要使用额外的数组空间,你必须仅使用 O(1) 额外空间并 原地 修改输入数组。元素的顺序可以改变。你不需要考虑数组中超出新长度后面的元素。
说明:
为什么返回数值是整数,但输出的答案是数组呢?
请注意,输入数组是以「引用」方式传递的,这意味着在函数里修改输入数组对于调用者是可见的。
你可以想象内部操作如下:
在这里插入图片描述
在这里插入图片描述

2.2.2 思路

这道题目的要求比较简单,总的来说就是要求读者删除数组当中的指定元素,返回最后得到的数组长度以及数组内容即可。——使用暴力算法即可完成,算法复杂度为O(n^2)。需要注意的是,

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值