这是一道局部翻转链表的题,可以这样实现:
假如要翻转链表的第M到第N个节点:
- 首先跳过待翻转链表的头M个节点
- 然后把第M+1个节点当做头节点,翻转N-M+1个节点
- 修改第M个节点的下一个节点为翻转后新的头节点
- 完成翻转
这里还使用了一个虚拟头节点的技巧,因为如果是从第一个节点开始翻转,那么当前头节点会被翻转到链表中间,而新的头节点变成了其他节点,增加虚拟头节点来辅助翻转逻辑,可以比较方便的保存头节点的引用。
下面是使用C语言实现的功能:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
// 翻转N个节点
struct ListNode* reverseN(struct ListNode* head, int n) {
if (n == 1) {
return head;
}
struct ListNode* next = head->next;
struct ListNode* curr = reverseN(next, n - 1);
head->next = next->next;
next->next = head;
return curr;
}
struct ListNode* reverseBetween(struct ListNode* head, int left, int right){
struct ListNode prevObject = {
.val = 0,
.next = head
};
struct ListNode* prev = &prevObject;
head = prev;
for (int i = 1; i < left; i++) {
head = head->next;
}
head->next = reverseN(head->next, right - left + 1);
return prev->next;
}