题目描述:
Reverse a linked list from position m to n. Do it in-place and in one-pass.
Given m, n satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.
Hide Tags Linked List
分析:
要求反转给定区间的链表节点,有至少有两种方法:
Reverse a linked list from position m to n. Do it in-place and in one-pass.
For example:
Given 1->2->3->4->5->NULL, m = 2 and n = 4,return 1->4->3->2->5->NULL.
Given m, n satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.
Hide Tags Linked List
分析:
要求反转给定区间的链表节点,有至少有两种方法:
方法一、暴力法,需要区间长度的额外空间,思路是:新建一个链表,存放给定区间节点的反转,然后再插入到原链表中。此法需要记录区间开始的前一个节点和结束的后一个节点。处理过程和206 Reverse Linked List的暴力法是一样的。
以下是C++实现以及注释:
/*///0ms*/
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
if(head == NULL || head->next == NULL || m == n)
return head;
ListNode* cur = head;
ListNode* before_m = NULL;
int count = 1; // 节点计数
if(m > 1) //当开始节点不是头节点时
{
while(count < m) //标记区间开始之前的那个节点。循环结束后,cur节点是区间开始的节点
{
before_m = cur;
cur = cur->next;
count++;
}
while(count < n ) // 因为cur原本就在before_m后面,所以只需将区间(m.n]之间的节点依次移动到before_m之后
{
ListNode* tmp= new ListNode(cur->next->val); //构造节点,元素值等于cur后面一个节点的值
tmp->next = before_m ->next; //将tmp插入到before_m后面
before_m ->next = tmp;
cur->next = cur->next->next; //删除cur的后续节点
count++;
}
return head; //返回修改后的链表
}
else //区间开始的节点是头节点,可以用一个新节点指向头节点作为区间开始之前的节点
{
before_m = new ListNode(0);
before_m->next = head;
while(count < n )
{
ListNode* tmp= new ListNode(cur->next->val);
tmp->next = before_m ->next;
before_m ->next = tmp;
cur->next = cur->next->next;
count++;
}
return before_m->next; 返回修改后的链表
}
}
};