剑指 Offer 24. 反转链表
注:本题与206. 反转链表相同
题目描述:
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
题目描述:
给你单链表的头节点head
,请你反转链表,并返回反转后的链表。
示例 1:
输入:head = [1,2,3,4,5]
输出:[5,4,3,2,1]
示例 2:
输入:head = [1,2]
输出:[2,1]
示例 3:
输入:head = []
输出:[]
提示:
链表中节点的数目范围是 [0, 5000]
-5000 <= Node.val <= 5000
进阶:
链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?
反转链表是很重要的基本功,对于解答很多与链表相关的题目都有很大帮助,也是其基础。
方法一:迭代
迭代法是最直接的将当前链表从前往后逐个反转结点指向的方法,其主要思路为:
1.设置一个当前节点cur初始化为传进来的头结点head,初始化时表示当前节点即为头结点,迭代时表示当前需要处理指向的结点;
2.设置一个前驱结点pre初始化为null,初始化时表示为链表反转后最后一个结点(即初始时的头结点)指向空null,迭代时表示当前节点(本来指向下一个)现在需要指向的结点,即原来的前驱作为现在的后继;
3.开始迭代:只要当前节点非空,
3.1就将当前结点的下一个结点先用一个临时结点temp保存下来,
3.2随后即可将当前节点的后继节点改为原来的前驱结点pre,
3.3改变后就将当前节点作为下一次迭代时的前驱结点,
3.4最后将当前节点的下一个结点设置为新的当前节点。
4.返回最后的前驱结点pre,因为此时的cur已经为null(原来链表尾部的指向)。
执行结果:通过
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:38.2 MB, 在所有 Java 提交中击败了52.74%的用户
通过测试用例:27 / 27
/**
* 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;//将传进来的节点设置为当前节点,由此开始迭代
while(cur!=null){//继续迭代
//由于要反转链表,那么当前节点指向的结点需要改为其上一个结点
//所以需要将当前节点的写一个结点先保存下来,以免丢失
ListNode temp=cur.next;
//保存后就可以开始反转,将当前指针指向其上一个结点
cur.next=pre;
//反转后将当前节点设置为所谓的“上一个结点”
pre=cur;
//将当前节点的下一个结点设置为所谓的“当前节点”
cur=temp;
}
return pre;//返回头结点,因为最后一次cur=temp;之后cur指向null
}
}
方法二:递归
递归的关键在于:先递归找到原来的尾节点,将其设置为新的头结点,然后开始跳出递归,此时实现由后向前地获取每个结点(后文的自己),将下一个结点的后继指向自己即可实现反向。
执行结果:通过
执行用时:0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗:38.4 MB, 在所有 Java 提交中击败了13.24%的用户
通过测试用例:27 / 27
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode(int x) { val = x; }
* }
*/
class Solution {
public ListNode reverseList(ListNode head) {//递归
//由于传进来的是head的下一个,所以此处判断的是下一个||下一个的下一个!!
if(head==null || head.next==null){
return head;
}
//直至得到最后一个结点,即为新的头结点
//注意此处传进去的是head结点的下一个
ListNode newHead=reverseList(head.next);
//最多只会递归到倒数第二个结点,因为最后一个节点已经满足if了,所以不用担心此处的空指针问题
//即4的下一个的下一个(为5)指向4,由此实现反转--就地反转,但递归需要用栈
head.next.next=head;
//需要将当前节点的下一个指向为null,避免最后变成环
head.next=null;
return newHead;
}
}
平平无奇小白程序媛一枚,欢迎各位大佬交流指教,如有不正确的地方,欢迎留言改正,谢谢!!!