今日打卡 Leetcode 206 题反转链表。链表类的题目要求候选人十分细心,因为很容易就出现空指针或者环等。
题目:
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
迭代解法
解法思路详解:拿到题目首先我想的是用迭代解法来解题,递归解法还是有点难度的,不容易想到。
迭代解法简单来说就是得初始化当前节点 cur、前置节点 prev 和下一个节点 nextNode,然后进行反转操作之后向右移动,直到当前节点 cur 为 null,我们返回最后一个非空节点 prev,作为反转链表的头。
public ListNode reverseList(ListNode head) {
ListNode prev = null;
ListNode cur = head;
while (cur != null) {
// 需要提前保存当前节点的下一个节点。
ListNode nextNode = cur.next;
cur.next = prev;
prev = cur;
cur = nextNode;
}
return perv;
}
时间复杂度 O(n)
空间复杂度 O(1)
递归解法
递归解法首先思考一个问题,假如只有两个节点比如:
4->5->NULL
head 指向 4,递归解法中的递完成反转的动作可以这样写:
head.next.next = head;
head.next = null
所以链表就变成了
NULL<-4<-5
最小子问题的终止条件为当链表的长度小于等于 1 的时候即
head == null || head.next == null
所以我们可以写出递归解法的代码:
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)
空间复杂度 O(n)