题目描述
- 输入一个链表,反转链表后,输出链表的所有元素
- 地址:牛客链接
解决方法
- 这是道最简单的链表调整题,对于链表调整题,一般两种做法:
- 不用额外空间,直接调整next指针(一般面试中回答这种方法)
- 采用额外空间,例如新建链表或者用集合或栈存储,处理后再将集合内的元素串成一条链表(笔试中,不会上一种方法,可以采用这种)
- 针对该题,具体有三种做法:
- 在原链表上调整
从第一个节点开始调整next指针,让curNode 的next指针指向上一个节点,所以要用一个变量维持上一个节点。又因为调整next指针后,会导致curNode在原链表中的下一个节点找不到了,所以必须在调整next指针之前,用nextNode临时保存下一个节点,反转完成后,迭代更新。直至curNode指向null。 - 递归解法
先对当前节点后面的链表进行反转(递归),然后将当前节点连在反转后的链表的后面(head.next.next = head),并把当前节点的next置null,注意这两步的顺序。完成整条链表的反转。base case为链表为空或者至于一个元素时,直接返回。 - 用栈
利用栈LIFO的特点,遍历链表,将值入栈,然后出栈,串成一个链表
经验教训
- 链表调整的两种解题方向
- 链表调整,一定要注意防止空指针异常,防止链表断裂(后面元素找不到了,用临时变量保存),判断链表是否为空,防止无限循环(调整后结尾的next未置null)
- 链表调整题,在纸上画一画,思路十分清晰。
代码实现
/*
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}*/
public class Solution {
public ListNode ReverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode preNode = null;
ListNode curNode = head;
ListNode nextNode = null;
while (curNode != null) {
nextNode = curNode.next;
curNode.next = preNode;
preNode = curNode;
curNode = nextNode;
}
return preNode;
}
/*
public ListNode ReverseList(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode tail = ReverseList(head.next);
head.next.next = head;
head.next = null;
return tail;
}
*/
}