Reverse a singly linked list.
Example:
Input: 1->2->3->4->5->NULL Output: 5->4->3->2->1->NULLFollow up:
A linked list can be reversed either iteratively or recursively. Could you implement both?
迭代是从前往后依次处理,直到循环到链尾;而递归恰恰相反,首先一直迭代到链尾也就是递归基判断的准则,然后再逐层返回处理到开头。总结来说,链表翻转操作的顺序对于迭代来说是从链头往链尾,而对于递归是从链尾往链头。
迭代法: 时间复杂度O(n),空间复杂度O(1)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode cur = head; //用来保存当前节点
ListNode prev = null; //因为要用到前一个结点,所以使用prev结点保存
while(cur!=null){
ListNode next = cur.next; //next结点用来保存cur.next指针域
cur.next = prev; //注意顺序
prev = cur;
cur = next;
}
return prev; //结束时,cur结点为空,prev结点为链表最后一个结点
}
}
递归法:时间复杂度O(n),空间复杂度O(n)
图1:链表反转结果
递归时,考虑把问题规模减小,假设我们的程序能够正常反转,则结果如下
反转后,1元素并没有任何操作,所以反转1的next仍然指向2,接下来只要将2的next指向1,而1的next指向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;} //head表示链表为空head.next是递归终止
ListNode temp = head.next;
ListNode newHead = reverseList(head.next); //前几行用来遍历到最后一个结点
temp.next = head; //反转链表
head.next = null; //避免出现环
return newHead;
}
}