题目描述
给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。
解题思路
想要反转链表部分节点可分为以下两步:
- 反转第left个到第right个节点
- 将反转后的链表和原来的链表重新连接
为了实现第二步,我们需要在遍历过程,找到4个位置:
left节点的前一个节点:此节点需要重新指向反转后的链表的第一个节点
left节点:开始反转的节点
right节点:需要反转的最后一个节点
right节点下一个节点: 反转后的链表尾需要指向这个节点
解题代码
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseBetween(struct ListNode* head, int left, int right){
int i = 0;
struct ListNode *tmp = NULL;
struct ListNode *rightPtr = NULL;
struct ListNode *leftPrev = NULL;
struct ListNode *leftPtr = NULL;
struct ListNode *rightNext = head;
while (i != right)
{
++i;
if (i < left)
{
if (i == left - 1)
{
leftPrev = rightNext; // 记录left前一个节点
}
rightNext = rightNext->next;
continue;
}
if (leftPtr == NULL)
{
leftPtr = rightNext; // 记录left节点
}
// 反转链表
tmp = rightNext->next;
rightNext->next = rightPtr;
rightPtr = rightNext;
rightNext = tmp;
}
struct ListNode *newHead;
// 当 left == 1, left没有前一个节点,此时新链表的头位right节点
if (leftPrev != NULL)
{
leftPrev->next = rightPtr;
leftPtr->next = rightNext;
newHead = head;
}
else
{
leftPtr->next = rightNext;
newHead = rightPtr;
}
return newHead;
}