您现在的位置是:首页 >技术教程 >剑指 Offer 24. 反转链表网站首页技术教程

剑指 Offer 24. 反转链表

不 良 2024-06-19 13:56:33
简介剑指 Offer 24. 反转链表

? 作者简介:一名在后端领域学习,并渴望能够学有所成的追梦人。
? 个人主页:不 良
? 系列专栏:?剑指 Offer 链表
? 学习格言:博观而约取,厚积而薄发
? 欢迎进来的小伙伴,如果小伙伴们在学习的过程中,发现有需要纠正的地方,烦请指正,希望能够与诸君一同成长! ?


剑指 Offer 24. 反转链表

题目:

定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。

示例:

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

限制:

0 <= 节点个数 <= 5000

思路一:

双指针法:可以通过改变链表中节点的next指针的指向从而实现链表的反转。

1.设置两个节点prevcurcur表示当前节点,prev表示当前节点的上一个节点,初始状态设置为prev = nullptr; cur = head;再设置一个结点tmp记录cur的下一个结点,即tmp = cur->next

2.改变cur结点next指针的指向,让其指向前一个结点prev,然后再通过prev = cur; cur = tmp; tmp = cur->next 更新cur节点、prev节点和tmp节点;

3.依次向后循环,当cur为空的时候,说明已经遍历完所有的节点,此时prev指向的节点就是反转后链表的头节点,返回的时候返回prev

image-20230516093339181

代码如下:

class Solution {
public:
    ListNode* reverseList(ListNode* head) {
        ListNode* cur = head; 
        ListNode* prev = nullptr;
        while(cur)
        {
            ListNode* tmp = cur->next; //保存cur的下一个结点
            cur->next = prev;
            prev = cur;
            cur = tmp; 
        }
        return prev;
    }
};

时间复杂度:O(N)

空间复杂度:O(1)

思路二:

递归:递归法和双指针法的逻辑相同,也是通过改变指针的指向从而实现反转。

1.递归函数中当cur不为空的时候,先记录下cur节点的下一个节点,再改变cur节点的next指针使其指向prev

2.发生递归,递归参数中的curtmp传到下一层函数后,cur充当prevtmp充当cur

3.当cur为空时递归结束,返回prev结点,此时的prev结点就是反转后的头结点;

双指针法中的循环以及pre = cur; cur = temp;通过递归实现了。

代码如下:

class Solution {
public:
    ListNode* Reverse(ListNode* prev,ListNode* cur)
    {
        if(cur == nullptr)
        {
            //当cur为空的时候,已经遍历完成,此时prev就是反转后链表的头节点 
            return prev;
        }
        ListNode* tmp = cur->next;
        cur->next = prev;//改变cur的next指针指向
        return Reverse(cur,tmp);
    }
    ListNode* reverseList(ListNode* head) {
        return Reverse(nullptr,head);
    }
};

时间复杂度:O(N)

空间复杂度:O(N)

风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。