Reverse a singly linked list.
Hint:
A linked list can be reversed either iteratively or recursively. Could you implement both?
1 iteratively
原本的链表如果是这样的话:
1 --> 2 --> 3 --> 4 --> 5
我们要做的就是:
1 <-- 2 <-- 3 <-- 4 <-- 5
所以其他的不变,只是改变next的指向即可。在修改一个节点的next之前,一定要先保存这个值。值得注意的一点是,1 与 2 之间,不光要将箭头方向改为 2 指向 1,也要把节点 1 的next 设为 null,不然会报错。即head.next = null。
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverseList(ListNode head) {
if(head == null) return null;
//如果只有一个节点,根部不用reverse,直接返回head
if(head.next == null) return head;
ListNode pre, curr, nx;
pre = head;
curr = head.next;
head.next = null;
while((nx = curr.next) != null){
curr.next = pre;
pre = curr;
curr = nx;
}
curr.next = pre;
return curr;
}
}
2 recursively
因为递归并没有迭代那么直观,所以博主对于要用递归求解的题目往往反应很慢,对于一些递归的代码也需要花较多的时间思考,所以博主在这里理一理思路,锻炼一些“递归思维”。对递归比较拿手的直接看代码就好。
还是拿
1 --> 2 --> 3 --> 4 --> 5
举例。
既然要用递归来写,那么一定有收敛条件,很明显,在上面就已经发现了:
if(head == null) return null;
//如果只有一个节点,根部不用reverse,直接返回head
if(head.next == null) return head;
然后递归就是在方法里面调用方法本身,但是参数是将原求解域缩小之后的输入,所以这里的递归合理猜测为:
reverseList(head.next);
产生的效果应该是:
1 --> 2 <-- 3 <-- 4 <-- 5
返回值是节点5的引用。那么增加哪些操作才能与这递归后的结果结合在一起,得到最后的答案(1 <– 2 <– 3 <– 4 <– 5)呢?我想聪明的你早已发现:将节点2的next指向节点1,节点1的next改为null不就好了嘛。
所以,完整的递归代码是:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
public class Solution {
public ListNode reverseList(ListNode head) {
if(head == null) return null;
if(head.next == null) return head;
ListNode result = reverseList(head.next);
ListNode l2 = head.next;
l2.next = head;
head.next = null;
return result;
}
}
402



被折叠的 条评论
为什么被折叠?



