day131—链表—反转链表Ⅱ(区域反转)(LeetCode-92)

题目描述

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

示例 1:

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

示例 2:

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

提示:

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

解决方案:

这段代码的核心功能是反转单链表中指定区间 left, right 内的节点 (比如原链表 1→2→3→4→5,left=2、right=4 时,反转后为 1→4→3→2→5),采用「迭代法 + 虚拟头节点」实现,时间复杂度 O(n)、空间复杂度 O(1),是区间反转链表的经典解法。

核心逻辑

代码通过 "定位反转起点 + 局部反转 + 重新连接" 三步完成区间反转,核心是用虚拟头节点规避头节点反转的边界问题:

  1. 虚拟头节点与定位前驱 :创建虚拟头节点 dx 指向原链表头,先找到反转区间的前驱节点 p0(即 left 位置的前一个节点),避免反转头节点时的空指针问题;
  2. 局部区间反转 :以 p0->next 为起点,用 pre/cur/nxt 三个指针,迭代反转 left, right 范围内的节点(反转逻辑和完整反转链表一致);
  3. 重新连接链表 :反转完成后,将原反转起点的节点(现在是反转区间的尾节点)指向反转区间后的第一个节点 cur,再将 p0 指向反转区间的新头节点 pre,恢复链表完整性;
  4. 返回结果 :最终返回虚拟头节点的 next(即新链表的头节点)。

总结

  1. 核心思路:用虚拟头节点简化边界处理,先定位反转区间前驱,再局部反转,最后重新拼接链表;
  2. 关键操作:反转后 p0->next->next = cur 和 p0->next = pre 是重新连接链表的核心,避免区间反转后链表断裂;
  3. 效率特点:一次遍历完成定位 + 反转 + 拼接,时间 O(n)、空间 O(1),是区间反转链表的最优解法。

函数源码:

cpp 复制代码
/**
 * 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 dx(0,head);
        
        ListNode* p0=&dx;
        for(int i=0;i<left-1;i++){
            p0=p0->next;
        }//到达反转区域的前一个结点:p0

        ListNode* nxt=nullptr;
        ListNode* pre=nullptr;
        ListNode* cur=p0->next;//反转的起始节点:p0->next
        for(int i=0;i<right-left+1;i++){
            nxt=cur->next;
            cur->next=pre;
            pre=cur;
            cur=nxt;
        }
        p0->next->next=cur;
        p0->next=pre;
        return dx.next;
    }
};
相关推荐
Tisfy2 小时前
LeetCode 0301.删除无效的括号:二进制枚举 / 回溯
算法·leetcode·字符串·题解·回溯·括号匹配·二进制枚举
Nil2082 小时前
leetcode 322零钱兑换
算法·leetcode·职场和发展
yi0112 小时前
DAY24: LeetCode 167:两数之和 II|从暴力枚举到左右双指针
笔记·python·算法·leetcode·二分查找·双指针
木井巳2 小时前
【BFS 解决拓扑排序】课程表
java·算法·leetcode·广度优先·宽度优先·推荐算法·图搜索算法
yi0113 小时前
LeetCode 15:三数之和|排序 + 双指针,如何避免重复答案?
笔记·python·算法·leetcode·双指针
alphaTao4 小时前
LeetCode 每日一题 2026/10/5-2026/10/11
算法·leetcode
longlongzihan6 小时前
LeetCode 41. 缺失的第一个正数:从基础解法到原地哈希
c++·算法·leetcode
java_nnnn7 小时前
LeetCode刷题双指针(快乐数+盛最多水的容器)Java
算法·leetcode·职场和发展
yi01116 小时前
LeetCode 219:存在重复元素 II——哈希表记录“最近一次出现的位置”
数据结构·人工智能·笔记·python·算法·leetcode·哈希表
好想像大佬一样能够ak所有20 小时前
Leetcode35.搜索插入位置
数据结构·算法·leetcode