题解 | #链表内指定区间反转#
链表内指定区间反转
https://www.nowcoder.com/practice/b58434e200a648c589ca2063f1faf58c
/**
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
class Solution {
public:
/**
*
* @param head ListNode类
* @param m int整型
* @param n int整型
* @return ListNode类
*/
ListNode* reverseBetween(ListNode* head, int m, int n) {
// write code here
int cnt=0;
ListNode *p=head;
ListNode *begin=NULL,*cur,*end=NULL;
while(p!=NULL){
cnt++;
if(cnt==m-1) begin=p;
if(cnt==m) cur=p;
// if(cnt==n) cur2=p;
if(cnt==n+1) end=p;
p=p->next;
}
ListNode *pre=NULL,*cur1=cur;;
while(cur!=end){
ListNode *tmp=cur->next;
cur->next=pre;
pre=cur;
cur=tmp;
}
cur1->next=end;
if(begin!=NULL){
begin->next=pre;
return head;
}
return pre;
}
};
首先要通过原链表得到几个关键节点信息:
begin:翻转区间的前一个节点,可能为NULL
cur:翻转区间的第一个节点
end:翻转的区间的后一个节点,用作判定循环结束的标志,可能为NULL
翻转部分当成普通的翻转链表来写,pre依旧为NULL,但是终止条件变为链表第n+1个节点,即end。
翻转后还需要接入原链表,此时需要判断翻转的第一个节点是不是链表头节点:
1.若翻转第一个节点是链表头节点,直接返回翻转的最后一个节点pre;
2.若不是,则将翻转后的链表接入begin节点后,返回head。
时间复杂度:O(n),空间复杂度O(1)
查看6道真题和解析
