LeetCode 206:反转链表
题目描述:
反转一个单链表。
【示例】
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
【进阶】
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
【难度】
容易
解题
题目很简单,反转链表有两个思路,恰好也是进阶所对应的两种方法。
方法1 双指针+循环
思路:要想反转链表,只需将当前节点放在下一节点之后。
用简单的例子描述过程,我们假设链表顺序为“A-B-C-D”:
- 将AB反转,结果是“B-A-C-D”,此时B位于链表头部。
- 将BC反转,得到“C-B-A-D”,此时C位于链表头部。
- 将CD反转,得到“D-C-B-A”,即最终结果。
具体操作是循环遍历整个链表,同时用两个指针,一个指针cur_head指向当前链表的头部节点,另一个指针cur_node指向当前节点。在循环体内部将cur_node的下一位置指向cur_head,再更新两个指针。需要注意的是,执行cur_node的下一位置指向cur_head操作之前,要保存原来cur_node后面的节点。
下面是该方法的具体代码:
/**
* 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_node=head, *temp_node;
head = nullptr;
while (cur_node){
temp_node = cur_node->next;
cur_node->next=head;
head = cur_node;
cur_node = temp_node;
}
return head;
}
};
值得注意的一点是,要假定在原有链表头部的前面还有一个空节点,这样反转之后,原链表第一个节点的下一位刚好为空。
方法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 == nullptr || head->next == nullptr)
return head;
ListNode * new_head = reverseList(head->next);
head->next->next = head;
head->next = nullptr;
return new_head;
}
};