反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
迭代法
定义两个指针,一个是要反转的节点指针(cur),一个是反转的节点要指向它前一个节点的指针(pre)。
比如开始的时候cur->1,pre->null;
第一次迭代:cur->pre,然后pre->cur,cur->下一个节点(当然下一个节点找不到了,需要你自己提前弄个引用)
对示例而言:1->null,pre->1,cur->2
第二次迭代:2->1->null,pre->2,cur->3
第三次迭代:3->2->1->null,pre->3,cur->4
第四次迭代:4->3->2->1->null,pre->4,cur->5
第五次迭代:5->4->3->2->1->null,pre->5,cur->null
(cur->null 迭代结束的标志)
代码:
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null){
return head;
}
ListNode pre = null,cur = head,next;
while(cur!=null){
next = cur.next;
cur.next = pre;
pre = cur;
cur = next;
}
return pre;
}
}
递归
1.非尾递归,即出栈时完成反转
第5次调用 | ... | head->5 5->4->3->2->1->null | ||
---|---|---|---|---|
第4次调用 | ... | head->4 p->? 5->4->3->2->1->null | ||
第3次调用 | ... | head->3 p->? 5->4->3->2->1->null | ||
第2次调用 | head->2 p->? 5->4->3->2->1->null | ... | head->2 p->? 5->4->3->2->1->null | |
第1次调用 | head->1 p->? 5->4->3->2->1->null | head->1 p->? 5->4->3->2->1->null | ... | head->1 p->? 5->4->3->2->1->null |
过程 | a | b | ... | e |
第5次调用 | return head->5 | |||||
---|---|---|---|---|---|---|
第4次调用 | return p->5 null<-4<-5 4->3->2->1->null return p->5 | |||||
第3次调用 | return p->5 null<-3<-4<-5 3->2->1->null return p->5 | |||||
第2次调用 | ... | |||||
第1次调用 | return p->5 null<-1<-2<-3<-4<-5 return p->5 | |||||
过程 | f(开始出栈) | g | h | ... | k | 最后返回p |
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null){
return head;
}
ListNode p = reverseList(head.next);
head.next.next = head;
head.next = null;
return p;
}
}