本题是一道简单题,解析本题的原因是本题的思想可以用于解决25. K 个一组翻转链表这道Hard题。

先看题目描述。定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

限制:

0 <= 节点个数 <= 5000

注意:本题与主站 206 题相同:https://leetcode-cn.com/problems/reverse-linked-list/

思路

比较容易想到的思路是双指针迭代,如同官方解析所说的:

假设链表为,我们想要把它改成

在遍历链表时,将当前节点的指针改为指向前一个节点。由于节点没有引用其前一个节点,因此必须事先存储其前一个节点。在更改引用之前,还需要存储后一个节点。最后返回新的头引用。

class Solution {
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode curr = head;
while (curr != null) {
ListNode next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
}
}

接下来换一种思路,我们新建一个节点prev来指向整个链表的头部,curr初始化为链表的头结点,然后每次只需将curr的下一个节点摘除,链接至prev之后即可。

prev-->1(curr)-->2-->3-->null
prev-->2-->1(curr)-->3-->null
prev-->3-->2-->1(curr)-->null

根据上述过程,得到另一个版本的迭代算法:

class Solution {
public ListNode reverseList(ListNode head) {
if (head == null) return null;
ListNode prev = new ListNode(-1), curr = head, tmp;
prev.next = head;
while (curr.next!= null) {
tmp = prev.next;
prev.next = curr.next;
curr.next = curr.next.next;
prev.next.next = tmp;
}
return prev.next;

}
}

我想,这个算法可能更容易理解和编写代码,接下来将使用这个思想解决个一组翻转链表的问题。

复杂度

时间复杂度线性,空间复杂度常数级。