编程语言
首页 > 编程语言> > 92. 反转链表 II(C++)

92. 反转链表 II(C++)

作者:互联网

目录

题目

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

示例 1:

image-20220309200738168

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

示例 2:

输入:head = [5], left = 1, right = 1
输出:[5]

提示:

题解

对于链表的问题,一般都是要建一个 dummy node连上原链表的头结点,以此来规范头节点变动和其他节点变动的代码,进行格式统一。

以题目中的例子来说,变换的是 2,3,4 这三个点,我们需要找到第一个开始变换结点的前一个结点,只要让 pre 向后走 m-1 步即可,用 pre 指向它。由于一次只能交换两个结点,所以我们按如下的交换顺序:

1 -> 2 -> 3 -> 4 -> 5 -> NULL
1 -> 3 -> 2 -> 4 -> 5 -> NULL // 第一次变换将结点 3 放到结点 1 的后面
1 -> 4 -> 3 -> 2 -> 5 -> NULL // 第二次变换将结点 4 放到结点 1 的后面

可以看出来,总共需要 right-left步即可,因为每次变换都是规律的操作,就以第一次变换进行举例。刚开始,pre 指向结点 1,cur 指向结点 2,然后我们建立一个临时的结点 tmp用临时变量保存某个结点就是为了首先断开该结点和前面结点之间的联系,这可以当作一个规律记下来。

每一次节点交换分为以下三个步骤:

这里跟常见的链表反转最大的区别在于以前prev、cur会向随着链表遍历反转逐渐向后移动,这里的prev、cur其实指向并没有改变。即这里的prev一直是1, cur一直是2, 是cur->next一直在变化

完整代码如下:

/**
 * 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(-1);
        dummy->next = head;
        ListNode* pre = dummy;
        // left-1是为了找到开始变换节点的前一节点
        for (int i = 0; i < left - 1; i++) 
            pre = pre->next;
        // 本题中pre和cur不会变动!!
        ListNode* cur = pre->next;
        for (int i = left ; i < right; i++) {
            ListNode* tmp = cur->next;
             // 首先断开临时节点和前面节点的关系
            cur->next = tmp->next;
            tmp->next = pre->next;
            pre->next = tmp;
        }
        return dummy->next;
    }
};

标签:pre,II,结点,ListNode,cur,next,链表,92,left
来源: https://www.cnblogs.com/buryinshadow/p/15986883.html