题解 | #链表内指定区间反转#
链表内指定区间反转
https://www.nowcoder.com/practice/b58434e200a648c589ca2063f1faf58c
/** * struct ListNode { * int val; * struct ListNode *next; * ListNode(int x) : val(x), next(nullptr) {} * }; */ 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 ListNode* p=head; // 最多只有一个元素或者反转的位置为同一个 if(p == nullptr || n == m){ return p; } ListNode* q=p->next; //有两个元素 if(q->next==nullptr){ q->next=p; p->next=nullptr; return q; } //三个元素以上 int i=1; ListNode* t=q->next; ListNode* first=nullptr; // ListNode* end=nullptr; while(i<n-1){ if(i==m-1){ first = p; } ///反转链表 if(i>=m) q->next=p; p=q; q=t; t=t->next; i++; } q->next=p; if(first==nullptr){ head->next=t; head=q; }else{ first->next->next=t; first->next=q; } return head; } };
一般链表题的话,可以先解决一般的情况,最后再考虑一些特殊情况。
一般的思路就是,我们要获取到开始进行反转序号的前一个结点(这里我命名为first),因为这个节点会帮助我们最后链表的拼接。然后就是在给定的区间将链表反转。反转完成之后,将我们获取到的first的next指向反转区间的下一个元素,再将first指向反转区间的最后一个元素。
特殊情况就是,给定的反转区间的开始序号是1,那么就无法获取到这个的前一个节点,并且序号为1的话也就代表当前位置就是头节点,那么这种情况到最后链表的拼接就要做一些特殊处理,若first是为空的,那么就将head的next指向反转区间的下一个元素,再将head变成反转区间的最后一个元素。