Description:
题目大意:给定一个单项链表,和m,n。要求反转 m 到 n 之间的链表。
解题思路:
算法标签:双指针
- 设置虚拟头节点,避免复杂头节点分类考虑
- left 指向第 m 个节点,right 指向第 n 个节点,pre 指向 left 的前一个节点,cur 指向 right 下一个节点。
- 反转 left 到 right 之间的节点
- 最后再接上即可
代码:
/*
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
// pre指向反转后的节点
ListNode* pre = NULL;
// cur指向当前节点
ListNode* cur = head;
// 迭代
while(cur != NULL) {
// cur_next 指向cur的下一个节点
ListNode* cur_next = cur -> next;
// 反转
// 当前节点指向前一个节点
cur -> next = pre;
// 前一个节点右移
pre = cur;
// 当前节点右移
cur = cur_next;
}
// 因为cur此时为NULL,pre为原链表的最后一个节点
return pre;
}
ListNode* reverseBetween(ListNode* head, int m, int n) {
// 设置虚拟头节点,避免复杂头节点分类考虑
// left 指向 m 节点,right 指向 n 节点
ListNode* dummyhead = new ListNode(0);
dummyhead -> next = head;
// pre指向 m 节点的左边
ListNode* pre = dummyhead;
for(int i = 0;i < m - 1;i++)
pre = pre -> next;
ListNode* left = pre -> next;
// 从 pre 走 right - left + 1 到 right 节点
ListNode* right = pre;
for(int i = 0;i < n-m+1;i++)
right = right -> next;
// cur 指向 right 的下一个节点
ListNode* cur = right -> next;
// 反转 left 到 right
// 切断链接
pre -> next = NULL;
right -> next = NULL;
// 反转局部链表
left = reverseList(left);
right = left;
while(right -> next != NULL)
right = right -> next;
// 接回原来的链表
pre -> next = left;
right -> next = cur;
return dummyhead -> next;
}
};