LeetCode->链表反转
这是一个很基础的题目。今天处理了一下,不论是以双指针迭代、递归等方法,都能处理,但是也使这个题目更为典型。
00 题目
提示:
-
链表中节点的数目范围是
[0, 5000]
-
-5000 <= Node.val <= 5000
01 双指针(迭代)
01-0 思路
-
定义两个指针: cop 和 temp ;cop 在前 temp在后。
-
每次让 cop 的 next 指向 temp ,实现一次局部反转
-
局部反转完成之后, cop 和 temp 同时往前移动一个位置
-
循环上述过程,直至 cop 到达链表尾部
01-1 代码
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode() : val(0), next(nullptr) {} 7 * ListNode(int x) : val(x), next(nullptr) {} 8 * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 * }; 10 */ 11 class Solution { 12 public: 13 ListNode* reverseList(ListNode* head) { 14 ListNode *re=NULL,*cop=head; 15 while(cop!=NULL){ 16 ListNode *temp = cop->next; 17 cop->next = re; 18 19 re = cop; 20 cop = temp; 21 } 22 return re; 23 } 24 };
02 递归
02-0 思路
总体思想是利用递归函数的函数栈来实现栈的特性。
-
使用递归函数,一直递归到链表的最后一个结点,该结点就是反转后的头结点,记作 ret.
-
此后,每次函数在返回的过程中,让当前结点的下一个结点的 next 指针指向当前节点。
-
同时让当前结点的 next 指针指向 NULL ,从而实现从链表尾部开始的局部反转
-
当递归函数全部出栈后,链表反转完成。
02-1 代码
1 class Solution { 2 public: 3 ListNode* reverseList(ListNode* head) { 4 if (head == NULL || head->next == NULL) { 5 return head; 6 } 7 ListNode* ret = reverseList(head->next); 8 head->next->next = head; 9 head->next = NULL; 10 return ret; 11 } 12 };
03 强化双指针
03-0 思路
-
原链表的头结点就是反转之后链表的尾结点,使用 head标记 .
-
定义指针 cur,初始化为 head .
-
每次都让 head 下一个结点的 next 指向 cur ,实现一次局部反转
-
局部反转完成之后,cur 和 head 的 next 指针同时 往前移动一个位置
-
循环上述过程,直至 cur 到达链表的最后一个结点 .
03-1 代码
1 class Solution { 2 public: 3 ListNode* reverseList(ListNode* head) { 4 if (head == NULL) { return NULL; } 5 ListNode* cur = head; 6 while (head->next != NULL) { 7 ListNode* t = head->next->next; 8 head->next->next = cur; 9 cur = head->next; 10 head->next = t; 11 } 12 return cur; 13 } 14 };