leetcode 206,Reverse Linked List,难度easy.
0. 题干
反转一个单链表。
示例:
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
进阶:
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
1. 解法一(双指针)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
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;
}
};
两个指针,一开始cur指向NULL,pre指向头结点;
t指向头pre下一个结点(头节点的下一个结点)
第一次pre的next指针指向cur,即pre的next指针指向NULL,
让cur等于pre,即cur前进一步,
pre等于t,即pre前进一步,
一直到pre等于NULL,链表翻转结束,之前以实现所以的翻转;
2. 解法二(递归)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
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;
}
};
递归的解法很简单粗暴,简单说就是把当前结点的下一个结点的next指针,指回当前节点,然后把当前结点指向NULL,这样递归来一波,就能把整个单链表逆序。
3. 解法三(双指针变异版本)
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;
}
};
这种解法是第一种的变异版本,这里重点解释下代码逻辑。
假设原单链表是五个结点;
进入while循环之前,head和cur都指向结点1;然后进while循环,t指向结点3,结点2的next指针
指回结点1;
cur递增进入结点2,头节点的next指针指向结点3,然后进while循环,此时t递增指向结点4,结点3的
next指针,指回结点2;
cur递增进入结点3,头节点的next 指针指向结点4,然后进入while循环,此时t递增指向结点5,结点4
的next指针,指回结点3;
cur递增进入结点4,头节点的next指针指向结点5,然后进入while循环,此时t递增指向 NULL,结点5的next指针,指回结点4;
cur递增进入结点5,头节点的next指针指向t,即头节点的next指针指向NULL,while循环结束,完美实现链表反转。