LintCode | 翻转链表II

http://www.lintcode.com/zh-cn/problem/reverse-linked-list-ii/#

http://www.lintcode.com/zh-cn/problem/reverse-linked-list-ii/#

思路1:两次遍历,第一次遍历保存下m到n节点的数据;第二次遍历修改m到n节点的数据(逆着替换)。需要额外O(n)的空间。

C++代码:

class Solution {
public:
    /**
     * @param head: The head of linked list.
     * @param m: The start position need to reverse.
     * @param n: The end position need to reverse.
     * @return: The new head of partial reversed linked list.
     */
    ListNode *reverseBetween(ListNode *head, int m, int n) {
        if (m >= n || head == NULL) {
            return head;
        }
        ListNode *cur = head;
        vector<int> helper(n-m+1);
        int cnt = 0, k = 0;
        while (cur != NULL) {
            cnt += 1;
            if (cnt >= m && cnt <= n) {
                helper[k++] = cur->val;
            }
            cur = cur->next;
        }

        cur = head; cnt = 0;
        while (cur != NULL) {
            cnt += 1;
            if (cnt >= m && cnt <= n) {
                cur->val = helper[--k];
            }
            cur = cur->next;
        }

        return head;
    }
};

思路2:in-place翻转。首先找到所制定的区间(端点),然后翻转区间,最后实施重连。不需要额外的空间。

  1. 创建dummy node,记下head;提醒一下,如果是C++,为了避免内存泄漏,创建dummy node时最好不要用ListNode *dummy = new ListNode(0),而是创建结构体:ListNode dummy(0),最后通过dummy.next返回。
  2. 通过一次遍历,找到第m个节点mth,第m个节点的前一个节点mth_prev,第n个节点,第n个节点的后一个节点nth_next
  3. 翻转指定区间的链表段(同翻转整个链表的方法)。一种方法是,先nth->next=NULL,然后调用Reverse Linked List的方法,输入为mth
  4. 重新连接链表。这时指定区间的链表已经反向,把mth_prevnth相连,mthnth_next相连。

C++代码:

class Solution {
public:
    /**
     * @param head: The head of linked list.
     * @param m: The start position need to reverse.
     * @param n: The end position need to reverse.
     * @return: The new head of partial reversed linked list.
     */
    ListNode *reverseBetween(ListNode *head, int m, int n) {
        if (!head->next) return head;
        
        ListNode dummy(0); dummy.next = head;
        ListNode *mth, *nth, *mth_prev = &dummy, *nth_next;
        for (int i = 1; i < n; ++i) {
            if (i == m - 1) mth_prev = head;
            head = head->next;
        }
        mth = mth_prev->next;
        nth = head;
        nth_next = nth->next;
        
        nth->next = NULL;
        reverse_list(mth);
        mth_prev->next = nth;
        mth->next = nth_next;
        
        return dummy.next;
    }
    
    void *reverse_list(ListNode *head) {
        ListNode *prev = NULL;
        while (head) {
            ListNode *next = head->next;
            head->next = prev;
            prev = head;
            head = next;
        }
    }
};
原文地址:https://www.cnblogs.com/ilovezyg/p/6379965.html