这个题目可以说是很经典了。当然思路也不难,主要分两种。递归法和迭代法,先说一下比较容易理解的迭代法。
1.迭代法
使用三个指针pre、cur、next
,然后每次都是更新cur
让其next指向pre
,然后next
则用来保存下一个cur
的位置,更新规则如下:
cur.next = pre; pre = cur; cur = next;
而且每次循环的开始或者说更新前都要记住最新的next,即next = cru.next;
。总的代码如下:
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null, cur = head, next = null;
while(cur != null) {
next = cur.next; //先要找到最新的next保存下来,然后更新
cur.next = pre; //反转
//寻找下一个待更新节点
pre = cur;
cur = next;
}
return pre;
}
}
2.递归法
递归法就有点难理解了说实话,画个图理解下吧。
当我们递归到某一层时,head指向的是3,然后然后假设4,5已经翻转好了,那我们当前就是要对head所指的节点进行翻转。但是要注意head此时的next(虚线部分)仍然是指向4的,因为我们还没有更改,所以此时我们翻转的操作就是head.next.next=head
让head原来的后继变为自己的前继,此时变为了图2的样子,但我们还要继续把虚线部分断开。最后返回这个p即递归到最底层时遇到的新的头结点。
public ListNode reverseList(ListNode head) {
if(head == null || head.next == null)
return head;
ListNode p = reverseList(head.next); //其实这个p就是为了传递新的头结点,对于翻转没有任何作用
head.next.next = head;
head.next = null;
return p;
}