力扣92题——反转链表 II

96 阅读1分钟

92. 反转链表 II

给你单链表的头指针 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]

思路

  1. 在第一次反转链表的基础上,使用四个指针记录当前遍历的位置(反转前的那个头,反转后的结尾,反转的第一个元素,反转的最后一个元素)。
  2. 把反转区域反转之后,只需要把反转区域头尾处理一下就行
  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* reverseBetween(ListNode* head, int left, int right) {
        if(head == nullptr) return head; 
        ListNode* dummyNode = new ListNode(-1); // 虚拟节点,防止处理头部多种情况
        dummyNode->next = head;
        ListNode* pre = dummyNode;
        while(left > 1) {
            pre = head;
            head = head->next;
            left--;
            right--;
        }
        ListNode* prevNode = nullptr;
        ListNode* curNode = head;
        ListNode* rLeft = head;
        ListNode* nextNode = head->next;
        while(nextNode && right > 1) {
            curNode->next = prevNode;
            prevNode = curNode;
            curNode = nextNode;
            nextNode = nextNode->next;
            right--;
        }
        ListNode* succ = curNode->next;
        curNode->next = prevNode;
        if(pre) pre->next = curNode;
        rLeft->next = succ;
        return dummyNode->next;
    }
};