来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/reverse-linked-list-ii
反转链表:
给你单链表的头节点 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
示例 1:
输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]
我们可以将该链表分成以下几个部分:头部、尾部、要反转的部分以及要反转部分的前后两个结点。
head | … | pre(left-1) | 要反转的部分 (left — right) | s(right+1) | 尾部 |
---|
我们可以先记录下pre和s两个结点,然后用另外两个结点去遍历left-right部分并将其反转,最后再让pre->next=right,left->next=s就可以了。当然还要注意对特殊情况的处理。
代码如下:
/**
* 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 *pre, *q, *p ,*s;
pre = head;
if(left >= right)return head;
for(int i = 1;i < left - 1;i++)
{
pre = pre->next;
}
q = pre->next;
p = q->next;
if(left == 1)
{
for(int i = 0;i < right - 2;i++)
{
q->next = pre;
pre = q;
q = p;
p = p->next;
}
head->next = p;
head = q;
head->next = pre;
return head;
}
if(right - left == 1)
{
pre->next = p;
q->next = p->next;
p->next = q;
return head;
}
s = p->next;
for(int i = 0;i < right - left - 1;i++)
{
p->next = q;
q = p;
p = s;
s = s->next;
}
pre->next->next = s;
p->next = q;
pre->next = p;
return head;
}
};