题目描述
反转一个单链表。
示例:
输入: head = [1, 2, 3, 4, 5]
输出: head = [5, 4, 3, 2, 1]
思路分析
这道题我们可以通过画图来梳理具体的步骤:
图1
如图1所示,我们以head = [1, 4, 3, 2, 5]
为例,(a)
为原链表,(b)
为输出链表。这里我们可以直观地看到改变的只有链表指针的指向,我们进一步细化,以节点1
为例:
图2
如果想改变节点1
的前置与后置指针指向,我们需要知道其前置节点与后置节点,之后需要进行如下操作:
图3
将核心代码单独拿出则有:
newPrev = curr.next; //prepare for new previous-node
// change pointers' direction
newPrev.next = curr;
curr.next = prev;
同样地,我们再来考虑节点4
:
图4
我们对比图3与图4,可以看出核心操作时一样的,但是在代码实现中,需要在操作每个节点后更新newPrev
与prev
.
步骤罗列
- 初始化三个指针
curr
、newPrev
与prev
; curr
遍历链表,改变指针方向后更新newPrev
与prev
;- 迭代终止条件为
curr = null
, 返回prev
;
解题代码
public static ListNode solution(ListNode head) {
if (head == null || head.next == null) {
return head;
}
//init pointers
ListNode prev = null;
ListNode curr = head;
ListNode nextPrev = null;
while(curr != null){
nextPrev = curr.next;
curr.next = prev;
prev = curr;
curr = nextPrev;
}
return prev;
}
复杂度分析
时间复杂度:我们对数据遍历了一次,时间复杂度为O(N);
空间复杂度:我们没有借助额外的容器,所以空间复杂度为常量级O(1)。
GitHub源码
完整可运行文件请访问GitHub。