题目
Reverse a linked list from position 0 to n-1.
For example: Given 1->2->3->4->5->nullptr,
return 5->4->3->2->1->nullptr.
分析
方法1 迭代
思路:
(1)已知原链表头节点指针head
(2)建立一个一个新节点dummy,令其next指针指向head
(3)从head开始,将之后的一个节点移到dummy node之后,重复此操作知道head成为末节点为止
将链表中元素按从左到右的顺序依次取出插入到dummy之后。(取数据时为从左到右,放数据为从右到左,从而完成rotate)
tips:
将链表中的一个节点p从原位置取出插入到另一个地方时的思路:
(至少要知道取出位置的前一个节点指针和插入位置的前一个节点指针)
(1)保存该节点,即赋给一个新的临时变量
(2)处理原位置前后节点的关系,即将前节点的next的next(后节点)赋给前节点的next。
(3)处理新位置处前后节点的关系,新位置的前一个节点通常都有指针标示,例如dummy,这里涉及到将一个节点插入到两个相邻的节点之间的问题(对于单链表来说,通常只用一个指向头节点的指针来表示,后面的节点没有直接的指针指向它,需要由前节点的next来表示,一旦和前节点脱离了就无法知道它的位置了,因此,在破坏节点间的链接时,要先给后节点一个指针来指向它,通常将新加入节点的next指针指向它)
代码
//迭代法(iterative)
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (!head) return head;
ListNode *dummy = new ListNode(-1);
dummy->next = head;
ListNode *cur = head;
while (cur->next) {
ListNode *tmp = cur->next;
cur->next = tmp->next;
tmp->next = dummy->next;
dummy->next = tmp;
}
return dummy->next;
}
};
方法2 递归(recursive)
思路
该题的递归是将大部分分解成小部分,最小部分的返回指针为最终的返回指针,只是在递归过程中改变了长度。
代码
(递归法)
class Solution {
public:
ListNode* reverseList(ListNode* head) {
//链表为空或只有一个节点时,即递归分解到最小的情况时的返回结果
if (!head || !head->next) return head;
ListNode *p = head;
//将下一节点反转后的返回值作为次步返还值,返回的链表头指针是不变的,只是长度变化
head = reverseList(p->next);
//将该节点和其原本的下一节点反转,并将该节点插入作为链尾
p->next->next = p;
p->next = NULL;
return head;
}
};