反转链表

题目

输入一个链表,反转链表后,输出链表的所有元素。

思路

这个很简单,我们使用三个指针,分别指向当前遍历到的结点、它的前一个结点以及后一个结点。

在遍历的时候,做当前结点的尾结点和前一个结点的替换。

方法一:迭代
假设存在链表 1 → 2 → 3 → Ø,我们想要把它改成 Ø ← 1 ← 2 ← 3。

在遍历列表时,将当前节点的 next 指针改为指向前一个元素。由于节点没有引用其上一个节点,因此必须事先存储其前一个元素。在更改引用之前,还需要另一个指针来存储下一个节点。不要忘记在最后返回新的头引用!

代码

迭代

/**
 * 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 prev = null;
        while (head != null) {
            ListNode nextTemp = head.next;
            head.next = prev;
            prev = head;
            //这两步相当于指针反转
            head = nextTemp;
        }
        return prev;
    }
}
复杂度分析

时间复杂度:O(n),假设 nn 是列表的长度,时间复杂度是 O(n)O(n)。
空间复杂度:O(1)。

递归
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;
}
时间复杂度:O(n),假设 nn 是列表的长度,那么时间复杂度为 O(n)O(n)。
空间复杂度:O(n),由于使用递归,将会使用隐式栈空间。递归深度可能会达到 nn 层。

 

 

以上的步骤是这样的理解

1 先把头结点之后的赋值给一个临时变量

2 把头结点之后的清空

3 把头结点赋值给后面的

4然后把临时变量赋值给前面的头结点