题目
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
数组逆序转换的方法
要想实现数组的逆序,方法有许多,如果只是打印那就跟简单了,可以类似遍历二叉树后序遍历那样递归,先去下个节点然后输出。当然今天我们并不是要输出,而是要真正的的改变链表的节点顺序。
我暂时先写了两个方法,当然这个题也可用栈(stack)来写,也是非常简单,相信你搞会了递归和双指针的话,栈也是手到擒来之。
一、递归
注意事项:
- 我们只需要改变节点中的next的指向即可,无需做其他操作
- 要花尽可能少的时间,也就是在遍历链表的时候一次性也修改指针的指向
- 记得修改原来的头结点的指向,要指向null,要么就会出现遍历输出时的最后两个节点的死循环,而导致超时问题
思路
- 创建一个全局变量(newFirst)来储存新链表的头结点
- 进程序前,先判定空链表和一个节点的链表
- 找到最后的节点是返回当前节点,更新新的头结点
- 递归每次返回的都是下一层新链表的最后一个节点,然后只需在当前层插入新的尾节点然后返回
图解
代码
class Solution {
//新的头结点
ListNode newFirst;
public ListNode reverseList(ListNode head) {
//先判定空链表和一个节点的链表
if (head == null || head.next == null) return head;
//进入递归
reverse(head);
//更新新链表尾节点(以前链表的头结点)的指向
head.next = null;
return newFirst;
}
public ListNode reverse(ListNode head) {
//递归终止:找到新链表头结点
if (head.next == null) {
newFirst = head;
return head;
}
//在 返回的 下一层 新链表的最后一个节点 之后插入 当前层的尾节点
reverse(head.next).next = head;
//返回当前层的尾节点
return head;
}
}
二、双指针
注意事项:
- 我们只需要改变节点中的next的指向即可,无需做其他操作
- 要花尽可能少的时间,也就是在遍历链表的时候一次性也修改指针的指向
- 记得修改原来的头结点的指向,要指向null,要么就会出现遍历输出时的最后两个节点的死循环,而导致超时问题
- 使用双指针来遍历链表,简化单指针的难度
- 在修改节点指向时,不要想反了,要不会出现意想不到的错误
思路
- 使用两个指针来控制链表,便于重接链表
- 进入循环,依次改变节点之间的指向
- 最后判定条件,跳出循环
图解
代码
class Solution {
public ListNode reverseList(ListNode head) {
//先判定空链表和一个节点的链表
if (head == null || head.next == null) return head;
ListNode pre = null, now = head ,tem;
while (now != null) {
//更改指针
tem = now.next;
now.next = pre;
pre = now;
now = tem;
}
//返回新链表头指针
return pre;
}
}