当前位置: 首页 > article >正文

【算法】链表:92.反转链表(medium)+双指针

 系列专栏

《分治》

《模拟》

《Linux》


目录

1、题目链接 

2、题目介绍

3、解法 (双指针)

4、代码


是 206. 反转链表 - 力扣(LeetCode)的类型题,且难度提升,可以先完成206,然后参照206的思路,解决本题。

1、题目链接 

 92. 反转链表 II - 力扣(LeetCode)

2、题目介绍

3、解法 (双指针)

  1. 创建虚拟节点
    • 为了简化边界情况的处理,尤其是当left为1时,即需要翻转的链表部分从头节点开始,此时我们难以直接操作头节点。因此,我们创建一个虚拟节点dummy,其next指向原链表的头节点head。这样,我们总可以操作dummy->next而无需担心修改原始头节点。
  2. 定位left位置的前一个节点
    • 我们需要遍历链表直到left-1的位置,以便找到left位置节点的前一个节点。这个节点在后续翻转过程中将作为新链表的尾部节点(因为它后面接的是需要翻转的部分),并且在翻转完成后,它将指向翻转后部分的新头节点。
    • 变量cur用于遍历链表,直到它指向left位置的前一个节点。
    • 终止位置是left-1。
  3. 准备翻转
    • pre指向left位置的节点,这是翻转部分的起始节点。
    • lLEFT存储left位置前一个节点的引用,这样在翻转后,我们可以将其与翻转后的链表部分重新链接。
  4. 执行翻转
    • 我们需要翻转从leftright的节点。
    • 使用三个指针pre(当前节点的前一个节点),pre->next(当前节点),和tmp(当前节点的下一个节点)。
    • 翻转操作通过改变节点间的next指针来实现:将当前节点的next指向它的前一个节点pre,然后移动precur指针到下一个节点。
    • 循环继续直到cur到达right位置的节点。此时,pre指向right位置的下一个节点,而cur指向right位置的节点。
  5. 重新链接
    • 翻转完成后,我们需要将翻转后的部分与链表的其他部分重新链接。
    • lLEFT->next->next指向right位置之后的节点(即pre),这是因为lLEFT->next现在是翻转部分的新头节点(原right位置的节点),而我们需要将它的next指向翻转部分之后的节点。
    • lLEFT->next指向翻转部分的新头节点(即原right位置的节点,现在的cur)。
  6. 返回结果
    • 虚拟节点dummynext指向原始链表的头节点或翻转后的新头节点(如果翻转从头部开始)。因此,返回dummy->next即可得到最终翻转后的链表。

4、代码

/**
 * 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* reverseBetween(ListNode* head, int left, int right) {
        ListNode* dummy = new ListNode(0);//虚拟结点
        dummy->next = head;
        ListNode* cur= dummy;

        //找到left位置的前一个结点
        for (int i = 0; i < left - 1; i++)
        {
            cur = cur->next;
        }
        
        ListNode* pre = cur->next;
        ListNode* lLEFT= cur;//用来存储left位置的前一个结点

        //翻转区域
        //保存头尾结点,方便之后和其他区域链接
        for (int i = left - 1; i < right; i++)
        {
            ListNode* tmp = pre->next;
            pre->next = cur;
            cur = pre;//cur最后会是right对应的结点
            pre = tmp;//PRE最后会是right的下一个结点
        }

        //链接翻转区域
        lLEFT->next->next = pre;
        lLEFT->next = cur;
        
        return dummy->next;
    }
};

💗感谢阅读!💗



http://www.kler.cn/news/331835.html

相关文章:

  • Leetcode: 0031-0040题速览
  • C++容器类型内置函数随笔
  • 62. 环境贴图2
  • 【openwrt-21.02】T750 openwrt switch划分VLAN之后网口插拔状态异常问题分析及解决方案
  • 【分布式微服务云原生】如何在ActiveMQ中优雅处理提前支付的延时订单
  • netty之Netty请求响应同步通信
  • mybatis-plus使用总结
  • YOLO11改进|注意力机制篇|引入注意力与卷积混合的ACmix
  • C语言 | Leetcode C语言题解之第455题分发饼干
  • 云原生数据库 PolarDB
  • 【AIGC】ChatGPT开发者必备:如何获取 OpenAI 的 API Key
  • 异常场景分析
  • 读数据湖仓06数据集成
  • 深度学习----------------------------编码器、解码器架构
  • 如何让服务器自动封禁低质量ip
  • 程序猿成长之路之设计模式篇——设计模式简介
  • C++——定义个一个结构体变量(包括年、月、日),编写程序,要求输入年、月、日,程序计算并输出该日在本年中是第几天。(提示:需要考虑闰年)
  • 酒店新科技,飞睿智能毫米波雷达人体存在感应器,智能照明创新节能新风尚
  • 掌握 C# 中的委托与事件机制
  • 微信小程序攻略:如何验证Token是否即将失效并自动刷新