- Reverse Linked List II
中文English
Reverse a linked list from position m to n.
Example
Example 1:
Input: 1->2->3->4->5->NULL, m = 2 and n = 4,
Output: 1->4->3->2->5->NULL.
Example 2:
Input: 1->2->3->4->NULL, m = 2 and n = 3,
Output: 1->3->2->4->NULL.
Challenge
Reverse it in-place and in one-pass
Notice
Given m, n satisfy the following condition: 1 ≤ m ≤ n ≤ length of list.
解法1:
参考了
http://bangbingsyb.blogspot.com/2014/11/leetcode-reverse-linked-list-ii.html
里面的图不错。
思路:
反转整个链表的变种,指定了起点和终点。由于m=1时会变动头节点,所以加入一个dummy头节点
代码如下:
/**
* Definition of singly-linked-list:
* class ListNode {
* public:
* int val;
* ListNode *next;
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param head: ListNode head is the head of the linked list
* @param m: An integer
* @param n: An integer
* @return: The head of the reversed ListNode
*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode * reverseBetween(ListNode * head, int m, int n) {
if (!head || (m >= n)) return head;
ListNode *dummy = new ListNode(0);
dummy->next = head;
head = dummy;
//get the m-1 th node
for (int i = 1; i < m; ++i) {
head = head->next;
}
ListNode *prev = NULL;
ListNode *cur = head->next; //the mth node
for (int i = m; i <= n; ++i) {
ListNode *temp = cur->next;
cur->next = prev;
prev = cur;
cur = temp;
}
head->next->next = cur;
head->next = prev;
head = dummy->next;
delete dummy;
return head;
}
};
解法2:用递归。先写出reverseN的版本。
/**
* Definition of singly-linked-list:
* class ListNode {
* public:
* int val;
* ListNode *next;
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param head: ListNode head is the head of the linked list
* @param m: An integer
* @param n: An integer
* @return: The head of the reversed ListNode
*/
ListNode* reverseBetween(ListNode *head, int m, int n) {
ListNode *dummy = new ListNode(0, head);
ListNode *p = dummy;
int cnt = n - m + 1; //note m value is changed below, so record cnt here.
while (--m) p = p->next;
p->next = reverseN(p->next, cnt);
return dummy->next;
}
private:
ListNode *reverseN(ListNode *head, int n) {
if (n == 1) return head;
ListNode *tail = head->next, *p = reverseN(head->next, n - 1);
//head->next = nullptr; //wrong,如果是反转整个链表可以用nullptr,但这里是反转部分,所以不行。
head->next = tail->next;
tail->next = head;
return p;
}
};
递归的另一个版本
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
if (!head || left == right) return head;
ListNode *dummy = new ListNode(0);
dummy->next = head;
ListNode *a = dummy;
for (int i = 1; i < left; i++) {
a = a->next;
}
// now a is the left node to the left
a->next = reverseFirstN(a->next, right - left + 1);
return dummy->next;
}
private:
ListNode* reverseFirstN(ListNode *a, int n) {
if (!a || n == 1) return a;
ListNode *pre = NULL, *tmp = NULL;
ListNode *origHead = a;
while (n) {
tmp = a->next;
a->next = pre;
pre = a;
a = tmp;
n--;
}
origHead->next = tmp;
return pre;
}
};
三刷:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int left, int right) {
ListNode *dummy = new ListNode(0);
dummy->next = head;
ListNode *start = head, *end = head, *pre = dummy, *post = NULL;
for (int i = 0; i < left - 1; i++) {
pre = pre->next;
}
ListNode *origPre = pre;
start = pre->next;
for (int i = 0; i < right - 1; i++) {
end = end->next;
}
post = end->next;
ListNode *origPost = post;
ListNode *node = start;
while (node != post) {
ListNode *tmp = node->next;
node->next = pre;
pre = node;
node = tmp;
}
return dummy->next;
}
};
稍微不同的版本
/**
* Definition of singly-linked-list:
* class ListNode {
* public:
* int val;
* ListNode *next;
* ListNode(int val) {
* this->val = val;
* this->next = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param head: ListNode head is the head of the linked list
* @param m: An integer
* @param n: An integer
* @return: The head of the reversed ListNode
*/
ListNode* reverseBetween(ListNode *head, int m, int n) {
ListNode *dummy = new ListNode(0), *pre = dummy, *start = NULL, *end = NULL;
dummy->next = head;
for (int i = 0; i < m - 1; i++) {
pre = pre->next;
}
start = pre->next;
end = start;
ListNode *origPre = pre;
for (int i = m; i <= n; i++) {
end = end->next;
}
ListNode *node = pre->next;
while (node != end) {
ListNode *tmp = node->next;
node->next = pre;
pre = node;
node = tmp;
}
origPre->next = pre;
start->next = node;
return dummy->next;
}
};