题解 | #链表内指定区间反转#
链表内指定区间反转
https://www.nowcoder.com/practice/b58434e200a648c589ca2063f1faf58c
/** * struct ListNode { * int val; * struct ListNode *next; * }; */ class Solution { public: /** * * @param head ListNode类 * @param m int整型 * @param n int整型 * @return ListNode类 */ ListNode* reverseList(ListNode* head){ if(head == nullptr || head->next == nullptr) return head; ListNode* lastNode = head; ListNode* currNode = head->next; ListNode* nextNode = nullptr; while(currNode != nullptr){ nextNode = currNode->next; currNode->next = lastNode; lastNode = currNode; currNode = nextNode; } return lastNode; } ListNode* reverseBetween(ListNode* head, int m, int n) { // write code here if(head == nullptr || m == n) return head; //重点:虚拟头节点(为了保证反转区间包含头节点的退化情况) //当反转区间包含头节点时,反转后的链表的真正头节点不再是head, //因此需要用vHead->next来记录反转后真正的头节点,以便返回之 ListNode* vHead = new ListNode(0); vHead->next = head; ListNode* currNode = vHead; ListNode* leftBreak = nullptr; //第一段链表的结尾 ListNode* left = nullptr; //第二段链表的开头 ListNode* right = nullptr; //第二段链表的结尾 ListNode* rightBreak = nullptr; //第三段链表的开头 //按题意,第一个元素下标为1。i = 0 时,currNode = vHead int i = 0; while(currNode != nullptr){ if(i == m-1){ leftBreak = currNode; left = leftBreak->next; } else if(i == n){ right = currNode; rightBreak = currNode->next; break; } currNode = currNode->next; i += 1; } //将链表切成三条 leftBreak->next = nullptr; right->next = nullptr; //对目标区间的那一条进行反转 reverseList(left); //将反转后的目标区间链表与首、尾的两段拼接 left->next = rightBreak; leftBreak->next = right; //注意释放创建在堆区的对象 currNode = vHead->next; delete vHead; vHead = nullptr; return currNode; } };
#数据结构编程链表#