LeetCode 92. Reverse Linked List II【链表,头插法】中等

本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章中,我不仅会讲解多种解题思路及其优化,还会用多种编程语言实现题解,涉及到通用解法时更将归纳总结出相应的算法模板。

为了方便在PC上运行调试、分享代码文件,我还建立了相关的仓库:https://github.com/memcpy0/LeetCode-Conquest。在这一仓库中,你不仅可以看到LeetCode原题链接、题解代码、题解文章链接、同类题目归纳、通用解法总结等,还可以看到原题出现频率和相关企业等重要信息。如果有其他优选题解,还可以一同分享给他人。

由于本系列文章的内容随时可能发生更新变动,欢迎关注和收藏征服LeetCode系列文章目录一文以作备忘。

给你单链表的头指针 head 和两个整数 leftright ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表

示例 1:

js 复制代码
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]

示例 2:

js 复制代码
输入:head = [5], left = 1, right = 1
输出:[5]

提示:

  • 链表中节点数目为 n
  • 1 <= n <= 500
  • -500 <= Node.val <= 500
  • 1 <= left <= right <= n

进阶: 你可以使用一趟扫描完成反转吗?


解法 一次遍历「穿针引线」反转链表

下面具体解释如何实现。使用指针变量来记录反转的过程中需要的变量,它们的意义如下:

  • curr :指向待反转区域的第一个节点
  • next永远指向 curr 的下一个节点 ,循环过程中,curr 变化以后 next 会变化;
  • p0 :永远指向待反转区域的第一个节点 left 的前一个节点,在循环过程中不变
  • prev :永远指向已反转区域的上个节点 ,紧邻在 curr 左侧。

操作步骤:

  1. 找到 p0 ,令 prev = nullptr, curr = p0->next
  2. 进入循环:
    1. 先将 curr 的下一个节点记录为 next
    2. 执行操作 ①:把 curr.next 指向上一个节点 prev
    3. 执行操作 ②:把 prev 指向当前节点 curr
    4. 执行操作 ③:把 curr 移动到下个节点 next
  3. 超出待反转区域后,p0->next 指向已反转区域的尾部,设置 p0->next->nextcurr ,再设置 p0->nextprev
cpp 复制代码
class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int left, int right) {
        // 设置 dummy 是此类问题的一般做法
        ListNode* dummy = new ListNode(0, head), *p0 = dummy;
        for (int i = 0; i < left - 1; ++i) p0 = p0->next;

        ListNode *prev = nullptr, *curr = p0->next;
        for (int i = 0; i < right - left + 1; ++i) {
            ListNode *next = curr->next;
            curr->next = prev;
            prev = curr;
            curr = next;
        }
        p0->next->next = curr;
        p0->next = prev;
        return dummy->next;
    }
};

复杂度分析:

  • 时间复杂度: O ( n ) \mathcal{O}(n) O(n) ,其中 n n n 为链表节点个数。
  • 空间复杂度: O ( 1 ) \mathcal{O}(1) O(1) ,仅用到若干额外变量。
相关推荐
shan_shmily40 分钟前
算法知识点————贪心
算法
寂柒1 小时前
C++——模拟实现stack和queue
开发语言·c++·算法·list
熬夜学编程的小王1 小时前
C++类与对象深度解析(一):从抽象到实践的全面入门指南
c++·git·算法
CV工程师小林1 小时前
【算法】DFS 系列之 穷举/暴搜/深搜/回溯/剪枝(下篇)
数据结构·c++·算法·leetcode·深度优先·剪枝
Dylanioucn1 小时前
【分布式微服务云原生】掌握 Redis Cluster架构解析、动态扩展原理以及哈希槽分片算法
算法·云原生·架构
繁依Fanyi1 小时前
旅游心动盲盒:开启个性化旅行新体验
java·服务器·python·算法·eclipse·tomcat·旅游
罔闻_spider1 小时前
爬虫prc技术----小红书爬取解决xs
爬虫·python·算法·机器学习·自然语言处理·中文分词
OLDERHARD2 小时前
Java - LeetCode面试经典150题 - 矩阵 (四)
java·leetcode·面试
Themberfue2 小时前
基础算法之双指针--Java实现(下)--LeetCode题解:有效三角形的个数-查找总价格为目标值的两个商品-三数之和-四数之和
java·开发语言·学习·算法·leetcode·双指针
陈序缘2 小时前
LeetCode讲解篇之322. 零钱兑换
算法·leetcode·职场和发展