题目
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.
Note:
Given m, n satisfy the following condition:
1 ≤ m ≤ n ≤ length of list.
分析
题目给定一个链表,以及两个整数,代表链表中节点的序列号,要求,将序列号之间的子链表反转,重新链接返回。
利用栈先进后出的思想,将要求反转的节点存入栈中,然后依次弹出,重新链接即可。
需要注意的是,要准确记录反转子链表的前一个节点以及后一个节点,以便正确链接。
AC代码
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n) {
if (head == NULL || m < 1 || n<1 || m >= n)
return head;
int len = 0;
ListNode *p = head;
//计算链表长度
while (p)
{
len++;
p = p->next;
}
//如果要反转的范围不符合要求则返回
if (m > len || n > len)
return head;
//声明一个栈,用来保存要求反转的子序列所有节点
stack<ListNode *> stk;
if (m == 1)
{
//若从头节点反转,特殊处理
ListNode *r = head;
while (m <= n && r != NULL)
{
stk.push(r);
r = r->next;
++m;
}
//新的头结点
head = stk.top();
stk.pop();
//链接剩下节点
ListNode *q = head;
while (!stk.empty())
{
q->next = stk.top();
q = q->next;
stk.pop();
}
//链接尾节点
q->next = r;
return head;
}
else{
ListNode *pre = head;
//找到要反转的第一个节点的前驱并保存
int i = 1;
while (i < m - 1)
{
pre = pre->next;
++i;
}
//将所有反转节点入栈,并保存尾
ListNode *r = pre->next;
while (m <= n)
{
stk.push(r);
r = r->next;
++m;
}//while
//链接
while (!stk.empty())
{
pre->next = stk.top();
pre = pre->next;
stk.pop();
}
pre->next = r;
return head;
}
return head;
}
};