反转链表
关键词:链表、双指针、递归
题目描述
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
示例 1:
1 2
| 输入: 1->2->3->4->5->NULL 输出: 5->4->3->2->1->NULL
|
思路
思路一:
好理解的双指针
定义两个指针: pre和 cur ;pre 在前 cur 在后;
每次让 pre 的 next 指向 cur ,实现一次局部反转;
局部反转完成之后, pre 和 cur 同时往前移动一个位置
循环上述过程,直至 pre 到达链表尾部
思路二:
简洁的递归
使用递归函数,一直递归到链表的最后一个结点,该结点就是反转后的头结点,记作 ret .
此后,每次函数在返回的过程中,让当前结点的下一个结点的 next 指针指向当前节点。
同时让当前结点的 next指针指向 NULL ,从而实现从链表尾部开始的局部反转;
当递归函数全部出栈后,链表反转完成。
思路三:
妖魔化的双指针
原链表的头结点就是反转之后链表的尾结点,使用 head 标记 .
定义指针 cur,初始化为 head .
每次都让 head 下一个结点的 next 指向 cur ,实现一次局部反转
局部反转完成之后,cur和 head的 next 指针同时 往前移动一个位置
循环上述过程,直至 cur 到达链表的最后一个结点 .
代码
思路一:
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Solution { public: ListNode* reverseList(ListNode* head) { ListNode* cur = NULL, *pre = head; while (pre != NULL) { ListNode* t = pre->next; pre->next = cur; cur = pre; pre = t; } return cur; } };
|
思路二:
1 2 3 4 5 6 7 8 9 10 11 12
| class Solution { public: ListNode* reverseList(ListNode* head) { if (head == NULL || head->next == NULL) { return head; } ListNode* ret = reverseList(head->next); head->next->next = head; head->next = NULL; return ret; } };
|
思路三:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| class Solution { public: ListNode* reverseList(ListNode* head) { if (head == NULL) { return NULL; } ListNode* cur = head; while (head->next != NULL) { ListNode* t = head->next->next; head->next->next = cur; cur = head->next; head->next = t; } return cur; } };
|
知识点
- 双指针的使用;
- 递归的使用;
- 链表的题要画图!