描述:给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
- 示例1 :
输入:head = [1,2,3,4,5] 输出:[5,4,3,2,1]
-
示例 2: 输入:head = [1,2] 输出:[2,1]
-
示例 3: 输入:head = [] 输出:[]
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/re…
解法1:双指针迭代法
-
解题思路:
- 采用前后双指针遍历,一个当前指针一个前指针,前指针初始为null,当前指针初始指向头节点head
- 遍历过程中,定义一个临时节点存储next节点,当前指针cur的next指向前指针pre,pre前进一位置为cur,cur前进一位置为刚刚临时保存的next节点
-
复杂度:
时间复杂度:O(n)空间复杂度:O(1) -
动画展示:
-
Java实现:
/**
* 双指针迭代法将链表反转 [时间复杂度:O(n) 空间复杂度:O(1)]
*
* @param head 链表(头节点)
* @return 反转后的新链表
*/
public static ListNode reverseList(ListNode head) {
ListNode pre = null;
// 当前节点
ListNode cur = head;
while (cur != null) {
// 记录当前节点的下一个节点
ListNode next = cur.next;
// 然后将当前节点指向pre
cur.next = pre;
// pre和cur节点都前进一位
pre = cur;
cur = next;
}
return pre;
}
解法2:递归法
-
解题思路:
- 递归的两个条件
- 终止条件是当前节点或者下一个节点为null
- 在函数内部,改变节点的指向,head的下一个节点指向head递归函数那句
head.next.next = head
- 递归的两个条件
-
复杂度:
时间复杂度:O(n)空间复杂度:O(n) -
动画展示:
-
Java实现:
/**
* 递归法将链表反转 [时间复杂度:O(n) 空间复杂度:O(n)]
*
* @param head 链表
* @return 反转后的新链表
*/
public static ListNode reverseList2(ListNode head) {
// 递归终止条件是当前为空,或者下一个节点为空
if (head == null || head.next == null) {
return head;
} else {
// 这里的cur就是最后一个节点
ListNode cur = reverseList2(head.next);
// 如果链表是 1->2->3->4->5,那么此时的cur就是5
// 而head是4,head的下一个是5,下下一个是空
// 所以head.next.next 就是5->4
head.next.next = head;
// 防止链表循环,需要将head.next设置为空
head.next = null;
return cur;
}
}