0X01 题目
Reverse a singly linked list.
Hint:
A linked list can be reversed either iteratively or recursively. Could you implement both?
0X02 题意
单链表反转。
0X03 题解
1.迭代(Dante:Java)
从论坛里面学来的一种解法。
这种方法会用到3个指针。
- head:永远指向链表的首个元素
- p:指向当前元素,每个循环后,它是已经反转过的链表段的最后一个元素。
- frontier:临时节点,指向p的下一个节点,每次循环后,翻转到head之前。
以a,b,c,d
为例:
初始状态,head指向a,p指向a,frontier指向空。
第一次循环中:frontier指向c,然后将p的next指向d,再将frontier指向head之前,最后把frontier变成head即可。具体逻辑看代码。
这是变换示例:
a,b,c,d
b,a,c,d
c,b,a,d
d,c,b,a
时间复杂度:O(N)
空间复杂度:O(1)
public class Solution {
public ListNode reverseList(ListNode head) {
if(head != null) {
ListNode p = head; //指向当前元素
ListNode frontier; //p的下一个元素,每次循环都会反转到head处
while(p != null && p.next != null) {
frontier = p.next;
p.next = p.next.next;
frontier.next = head;
head = frontier;
}
}
return head;
}
}
2.递归(Dante:Java)
好久不用递归了,差不多看不懂了,递归的思路不太好总结。大致思路是每次递归后的链表段是反转过的。
以数据a,b,c,d
为例。
- 最里层的一次递归返回到是
d
; - 然后倒数第二层返回
d,c
; - 倒数第三层返回
d,c,b
- 然后拼出来
d,c,b,a
假设现在传入b,c,d
进去,然后nextNode指向c
,
经过一次reverseList递归,newhead指向d
,并且newhead.next指向c
,
然后再执行nextNode.next = head;
后,nextNode.next指向b
,
此时返回newhead即可。
public class Solution {
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null) {
return head;
}
ListNode nextNode = head.next;
ListNode newHead = reverseList(nextNode);
nextNode.next = head;
head.next = null;
return newHead;
}
}
2016-08-04 19:33:39 hzct