链表的反转
以链表合并为例:https://leetcode.cn/problems/reverse-linked-list/
题目描述
给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。
1Solution 迭代 Accepted / Used 时空复杂度 O(n) O(1)
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null) return head;
ListNode cur = head, pre = null, front = null;
while(cur!=null) {
front = cur.next;//记录第三个几点的位置,防止链表丢失
cur.next = pre;//反转
//pre.next = null; 此处的指针不需要切断,因为上一次循环已经反转(相当于切断)
pre = cur;//往后移动
cur = front;
}
return pre;
}
//整理上面代码如下,相互对照理解
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null) return head;
ListNode cur = head, pre = null, front = null;
while(cur!=null) {
front = cur.next;
cur.next = pre;
pre = cur;
cur = front;
}
return pre;
}
2 Solution 递归 Accepted / Used 时空复杂度 O(n) O(n)
题解链接:https://leetcode.cn/problems/reverse-linked-list/solution/yi-bu-yi-bu-jiao-ni-ru-he-yong-di-gui-si-67c3/
递归的含义
对于结点1来说,它只需要知道它之后的所有节点反转之后的结果就可以了,也就是说递推公式reverseList的含义是:把拿到的链表进行反转,然后返回新的头结点。
//递归结束条件是l1或l2为空
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null) return head;
/*head.next是递归结束的条件,之所以是条件head.next!=null而不是head!=null,是因为,当只剩下一个节点的时
候就可以直接返回,二是条件head!=null会让以下的操作超出范围,head.next.next的相关操作*/
// 我们不需要知道1节点之后的情况,设计函数返回的是反转好后的链表(头结点)即可
ListNode newHead = reverseList(head.next);// 返回的结果是反转后的链表的头结点
head.next.next = head; //反转,Example 1->2,变成 2->1
head.next = null; //切断此处的指针,防止循环
return newHead;
}
//整理上面代码如下,相互对照理解
public ListNode reverseList(ListNode head) {
if(head==null||head.next==null) return head;
ListNode newHead = reverseList(head.next);
head.next.next = head;
head.next = null;
return newHead;
}