- LCR 024. 反转链表 - 力扣(LeetCode)LCR 024. 反转链表 - 给定单链表的头节点 head ,请反转链表,并返回反转后的链表的头节点。 示例 1:[https://assets.leetcode.com/uploads/2021/02/19/rev1ex1.jpg]输入:head = [1,2,3,4,5]输出:[5,4,3,2,1]示例 2:[https://assets.leetcode.com/uploads/2021/02/19/rev1ex2.jpg]输入:head = [1,2]输出:[2,1]示例 3:输入:head = []输出:[] 提示: * 链表中节点的数目范围是 [0, 5000] * -5000 <= Node.val <= 5000 进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题? 注意:本题与主站 206 题相同: https://leetcode-cn.com/problems/reverse-linked-list/ [https://leetcode-cn.com/problems/reverse-linked-list/]
https://leetcode.cn/problems/UHnkqh/
zhe206. 反转链表 - 力扣(LeetCode)206. 反转链表 - 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例 1:[https://assets.leetcode.com/uploads/2021/02/19/rev1ex1.jpg]输入:head = [1,2,3,4,5]输出:[5,4,3,2,1]示例 2:[https://assets.leetcode.com/uploads/2021/02/19/rev1ex2.jpg]输入:head = [1,2]输出:[2,1]示例 3:输入:head = []输出:[] 提示: * 链表中节点的数目范围是 [0, 5000] * -5000 <= Node.val <= 5000 进阶:链表可以选用迭代或递归方式完成反转。你能否用两种方法解决这道题?https://leetcode.cn/problems/reverse-linked-list/
这两题是一样的
首先是三指针解法:
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
/*先看题目给的定义格式,有一个val还有next*/
class Solution {
public:ListNode* reverseList(ListNode* head) {
/*传来一个head*///先判断链表为空或者链表数据只有一个的情况if(head==NULL||head->next==NULL)return head;//接下来我们要反转链表,需要用到三个参数,就像我们之前写数组交换数据的时候一样//由于题目中可以看见,最后一个数据为空1->2->3->4->5->NULLstruct ListNode *n1=NULL, *n2=head ,*n3=head->next;while(n2){n2->next=n1;//反转n1=n2;n2=n3;if(n3)n3=n3->next;}/*第一次:1->NULLn1=1,n2=2,n3=3可以看到整个数据往后移动了一位,原本是NULL,1,2第二次:2->1n1=2,n2=3,n3=4第三次:3->2n1=3,n2=4,n3=5注意 这个时候还未触发条件,这里我们就可以看到这时候链表菜反转到3,我们最后传回的也是n1这 个头结点第四次:4->3n1=4,n2=5,n3=NULL第五次:5->4n1=5,n2=NULL,N3=NULL到这里我们就可以看到上面的两个判断条件的原因1.由于最后要反转整个链表,返回的是n1,对于原链表来说,最后一个节点是NULL反过来其实就是NULL->5而我们反转的语句是n2->next=n1所以最后的判断条件即为n2==NULL的时候,循环结束反转2.最后n2==NULL的时候,n3不能再往后了,不然会出现空指针的情况,因为NULL后面没有NULL了所以最后n3需要判断,如果已经为空了就不需要再往后移动了*/return n1;}
};
头插法:
/*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next) {}* };*/
class Solution {
public:ListNode* reverseList(ListNode* head) {if(head==NULL||head->next==NULL)return head;//与上面同样的判断struct ListNode *cur=head , *next=head->next , *newhead=NULL;//定义三个指针,我们的目的是将newhead作为一个新的头,通过cur一个个头插while(cur){//同样的还是以cur为空作为循环的判断cur->next=newhead;newhead=cur;cur=next;//这里的判断与上一个解法一样if(next)next=next->next;/*第一次:cur=1,next=2,newhead=NULL将cur->next=newhead------- 1->NULL然后继续往后走 cur=2,next=3依次类推:2->1->NULLcur=3,next=43->2->1->NULLcur=4,next=5这里就可以看出来,如果判断条件是next==NULL,那这时的cur才等于5并且没有插到新链表中所以如果cur作为5也就是最后一个数插到新链表中,那么它在当次循环结束后的值就为NULL即cur==NULL作为循环结束标志*/}return newhead;}
};
大家也可以动手画一画,我不喜欢画图,喜欢脑子里想,虽然我知道这不是个好习惯