题目描述
反转一个单链表。
示例
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
题解
思路
改变链表的next指针的指向,直接将链表反转

首先定义一个cur指针,指向头结点,再定义一个pre指针,初始化为null。
然后就要开始反转了,首先要把 cur.next 节点用temp指针保存一下,因为接下来要改变 cur.next 的指向了,改变指向后cur向前移动时就需要temp。将cur.next 指向pre ,此时已经反转了第一个节点了。
接下来,就是循环走如下代码逻辑了,继续移动pre和cur指针。
最后,cur 指针已经指向了null,循环结束,链表也反转完毕了。此时我们return pre就可以了,pre指针就指向了新的头结点。
解法一(双指针法)
时间复杂度 O(n),空间复杂度 O(1)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
ListNode pre = null;
ListNode cur = head;
ListNode temp;
while (cur != null) { // 判定条件
temp = cur.next; // 暂存cur向后移动的节点
cur.next = pre; // 反转
pre = cur; // pre向前移动
cur = temp; // cur向前移动
}
return pre;
}
}
解法二(递归)
时间复杂度 O(n),空间复杂度 O(n)
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
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;
}
}
/*
按照递归,当执行reverseList(5)的时候返回了5这个节点,reverseList(4)中的p就是5这个节点,我们看看reverseList(4)接下来执行完之后,5->next = 4, 4->next = null。这时候返回了p这个节点,也就是链表5->4->null,接下来执行reverseList(3),代码解析为4->next = 3,3->next = null,这个时候p就变成了,5->4->3->null, reverseList(2), reverseList(1)依次类推,p就是:5->4->3->2->1->null
reverseList: head=1
reverseList: head=2
reverseList: head=3
reverseList:head=4
reverseList:head=5
终止返回
cur = 5
4.next.next->4,即5->4
cur=5
3.next.next->3,即4->3
cur = 5
2.next.next->2,即3->2
cur = 5
1.next.next->1,即2->1
最后返回cur
*/
递归二
class Solution {
public ListNode reverseList(ListNode head) {
// 与双指针初始化一样
// ListNode pre = null;
// ListNode cur = head;
return reverse(null, head);
}
public ListNode reverse(ListNode pre, ListNode cur) { // 不断地将 cur 指向 pre
if (cur == null) return pre;
ListNode temp = cur.next; // 新的cur
cur.next = pre;
return reverse(cur, temp); // cur就是新的pre
}
}