⭐️前面的话⭐️
大家好!博主开辟了一个新的专栏——剑指offer,我要开始刷题了!这个专栏会介绍《剑指offer》书上所有的面试编程题。并且会分享一些我的刷题心得。由于博主水平有限,如有错误,欢迎指正,如果有更好的解题思路和算法可以分享给博主哦!一起加油!一起努力!
📒博客主页:未见花闻的博客主页
🎉欢迎关注🔎点赞👍收藏⭐️留言📝
📌本文由未见花闻原创,CSDN首发!
📆首发时间:🌴2021年9月2日🌴
✉️坚持和努力一定能换来诗与远方!
💭参考书籍:📚《剑指offer第1版》,📚《剑指offer第2版》
💬参考在线编程网站:🌐牛客网🌐力扣
🙏作者水平很有限,如果发现错误,一定要及时告知作者哦!感谢感谢!
博主的码云gitee,平常博主写的程序代码都在里面。
⭐️剑指 Offer 24. 反转链表⭐️
🔐题目详情
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
限制:
0 <= 节点个数 <= 5000
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/
💡解题思路
方法1: 双指针迭代法。
假设反转对象节点为cur
,反转指向的结点为tail
,反转后tail
指向的结点为首结点。具体过程如下图:
时间复杂度: O(N)
方法2: 递归法。
简单来说就是先递进至最后一个结点,使最后一个结点为反转链表的头结点,然后在归出的过程中是后面的结点指向前面的结点,前面的结点指向空,最终实现链表反转。
时间复杂度: O(N)
🔑源代码
编程语言:C语言
在线编程平台:力扣
//方法1
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
struct ListNode* reverseList(struct ListNode* head){
if (head == NULL)
return NULL;
struct ListNode* cur = head;//反转对象节点,初始化第1个结点
struct ListNode* next = NULL;//储存cur下一个结点
struct ListNode* tail = NULL;//cur前插对象节点,反转后为反转链表的首结点
while (cur)
{
next = cur->next;
cur->next = tail;//进行前插
tail = cur;
cur = next;
}
return tail;
}
//方法2
struct ListNode* reverseList(struct ListNode* head){
/* 特判 */
if (head == NULL || head->next == NULL) {
return head;
}
//长度为n的链表,从最后一个结点开始需要进行n-1次反转操作
//从第一个结点到最后一个结点,会进入n次reverseList()函数,除去最后一次结点只会返回最后一个结点外,其他都会进行链表结点反转
//首先递进至最后一个结点,并保存这个结点作为反转链表后的头结点
struct ListNode *next = head->next;
struct ListNode *node = reverseList(next);
/* 归出过程中,每一次将结点反转 */
next->next = head;
/* 被指向的结点指向空 */
head->next = NULL;
return node;
}
🌱总结
对于链表的反转可以使用头插法或者递归实现。当然也可以根据栈先进后出的特点,使用栈反转链表。