struct ListNode
{
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
ListNode * reverseList(ListNode * head)
{
//ListNode * dummy = new ListNode(0);
//ListNode * ptr = head;
//while (head)
//{
// head = head->next;
// ptr->next = dummy->next;
// dummy->next = ptr;
// ptr = head;
//}
//return dummy->next;
//0->1->2->3->4->5
//0->5
//0->4->5->4->5......
//0->5->4
//
if (head == NULL || head->next == NULL)
return head;
ListNode *res = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return res;
}
这道题如果使用迭代解,那么很容易理解也很容易完成,但是本人在做完之后,看到leetcode上某位大神用递归解决的代码,十分震撼!
这位大神的解决方案是递归,由于本人水平尚低,所以理解这个解决方案花了非常多时间。总结下来大概是这样的思路:
假设现在链表head为1->2->3->4->5,
ListNode *res = reverseList(head->next);
reverseList函数的参数是head->next,这就相当于自身开始向后递归,过程如图所示:
当到达第五层时,函数进行第一次返回,返回值的链表只有5一个节点,因此res的值也是只有一个节点的链表,此时程序回到第四层,该层传入的链表有两个节点:4->5
head->next->next = head;
head->next = NULL;
return res;
该层的head进行了如下变换的过程
4->5 ==> 4->5->4-->5............
5->4
此时注意:对于我这类新手来说,最难理解的地方到了!
仔细观察堆栈的值的时候,发现执行完head->next->next=head的时候,res也从5跟着变成了4->5->4->5......,这是为什么呢?思考很长时间之后得到的答案是:指针你把他当作一个迭代器就可以了,在没有执行完这行代码前,res指向的节点5->next为空,执行完这句之后,该节点变成了5->4->5->4...所以,作为指向该链表的指针,指代的链表同样变为了:5->4->5->4......(注意节点的变化)
后续的每一层的变化是这样的:
第三层: head 3->4
res 5->4
head 3->4->3->4.... => 4->3
res 5->4->3
第二层: head 2->3
res 5->4->3
head 2->3->2->3.... => 3->2
res 5->4->3->2
第一层:head 1->2
res 5->4->3->2
head 1->2->1->2....=>2->1
res 5->4->3->2->1