题目
剑指 Offer 24. 反转链表
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
注意:本题与主站 206 题相同
思路
刚开始想的是直接利用栈的特性,全部压栈最后全部弹出就可以组好反转的链表,但是发现并不能超越100%的用户,随后改进了,不需要压栈,纯靠指针在操作。
比如1 2 3 4,head = 1我们先让root = head = 1 ,tmpNext = head.next = 2,让root.next = null;head = tmpNext = 2;其实就是把1拿出来做成了根节点(暂时的,根节点一直在变)
开始循环
拿出2,tmpNext临时存储上3,让2.next = root = 1,然后让root = head = 2 就搞成了链 2 1,再恢复头head = tmpNext = 3,如此循环下去就可以每次从原链表拿一个放到新链表的最前面,头插法。
代码
第一个栈实现版本
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {
Stack<ListNode> stack = new Stack<>();
//全部压栈
while (head != null){
stack.push(head);
head = head.next;
}
//弹出
if (stack.size() > 0){
ListNode ret = stack.pop();
ListNode p = ret;
while (!stack.isEmpty()){
ListNode t = stack.pop();
p.next = t;
p = p.next;
}
p.next = null;
return ret;
}
return null;
}
}
改进后的版本
/**
* 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){
return null;
}
ListNode root = head, tmpNext = head.next;
root.next = null;
head = tmpNext;
while (head != null) {
tmpNext = head.next;
head.next = root;
root = head;
head = tmpNext;
}
return root;
}
}