LeetCode Reverse Linked List II

92. Reverse Linked List II

Reverse a linked list from position m to n. Do it in one-pass.

Note: 1 ≤ m ≤ n ≤ length of list.

Example:

Input: 1->2->3->4->5->NULL, m = 2, n = 4
Output: 1->4->3->2->5->NULL

本题需要把链表中[m,n]之间的节点逆序,算是LeetCode Reverse Linked List的升级版,也是链表逆序的通用代码了。
思路简单,首先找到第m个节点,然后和LeetCode Reverse Linked List类似,用头插法把接下来的n-m+1个节点逆序就好了。
因为m可能等于1,为了统一代码,我们先在head前添加一个0号节点,这样操作起来更方便~然后开始找第m个节点,找到之后,把prior和tail切开,从tail开始往后把n-m+1个节点用头插法逆序。
有一个地方需要注意,就像样例一样,当把2~4逆序之后,我们还需要把最后节点5接到逆序之后的链表末尾,为了不再遍历链表,我们在找到第m个节点的时候,事先保存tail节点,也就是先保存2号节点,当逆序完之后,直接2->next=5就好了。
完整代码如下:

class Solution {
public:
    ListNode* reverseBetween(ListNode* head, int m, int n)
    {
        if (head == NULL || head->next == NULL || m == n)
            return head;
        ListNode* new_head = new ListNode(0);
        new_head->next = head;
        ListNode *prior = new_head, *tail = head, *mid_head, *tmp;
        int offset = 1;
        while (offset < m) {
            prior = prior->next;
            tail = tail->next;
            offset++;
        }
        mid_head = prior; // 需要逆序的前一个节点
        tmp = tail; // 保留已逆序的最后一个节点,也就是需要逆序的第一个节点
        while (offset <= n) {
            prior = tail;
            tail = tail->next;
            prior->next = mid_head->next;
            mid_head->next = prior;
            offset++;
        }
        tmp->next = tail; // 已逆序最后一个节点接上后续节点
        return new_head->next;
    }
};

本代码提交AC,用时3MS。这代码居然一遍写完AC,都没有经过调试,我觉得边界条件处理还是要比较细心。

Leave a Reply

Your email address will not be published. Required fields are marked *