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