LeetCode 206:反转链表

LeetCode 206:反转链表

题目描述:

反转一个单链表。
【示例】

输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL

【进阶】
你可以迭代或递归地反转链表。你能否用两种方法解决这道题?
【难度】
容易

解题

题目很简单,反转链表有两个思路,恰好也是进阶所对应的两种方法。

方法1 双指针+循环

思路:要想反转链表,只需将当前节点放在下一节点之后
用简单的例子描述过程,我们假设链表顺序为“A-B-C-D”:

  1. 将AB反转,结果是“B-A-C-D”,此时B位于链表头部。
  2. 将BC反转,得到“C-B-A-D”,此时C位于链表头部。
  3. 将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;
    }
};

你可能感兴趣的:(LeetCode,leetcode)