赞
踩
将一个节点数为 size 链表 m 位置到 n 位置之间的区间反转,要求时间复杂度 �(�)O(n),空间复杂度 �(1)O(1)。
例如:
给出的链表为 1→2→3→4→5→NULL, m=2,n=4,
返回 1→4→3→2→5→NULL.
数据范围: 链表长度 0<size≤1000,0<m≤n≤size,链表中每个节点的值都满足∣val∣≤1000
要求:时间复杂度O(n) ,空间复杂度O(n)
首先找到m位置的前一个节点和m所在节点,分别用两个指针指向。
第二步就是设立尾部节点的指针,防止最终尾部节点丢失与前后关联不上。
第三步就是单链表完全反转,这里如果有不太懂的可以去看我上一篇写的有关反转链表的部分,
最后就是将反转后的部分的头部与m的前一个节点相连,这里要注意如果前一个节点为空即m为head节点则直接让head = pPre。
- struct ListNode* reverseBetween(struct ListNode* head, int m, int n ) {
- // write code here
- if(head == NULL || head->next ==NULL)
- return head;
- struct ListNode* q = NULL,*p = head;
- for(int i = 0; i < m - 1; i++) {
- q = p;
- p = p->next;
- }
- //此时p指向第m个节点,q指向m前一个节点
- struct ListNode* end = p;//end用来指向逆序后的尾节点
- struct ListNode* pPre = p,*nxt = NULL;
- p = p->next;
- //我发现单链表逆序还真是都要用三个节点去指,nxt用以指向下一个节点,p节点拿来逆序,pPre拿来指向前一个节点
- for(int i = m + 1; i <= n; ++i){
- nxt = p->next;
- p->next = pPre;
- pPre = p;
- p = nxt;
- }
- end->next = p;//此时的p节点指向的是第n + 1个节点
- if(q){//注意q节点可能为空
- q->next = pPre;
- }else{
- head = pPre;
- }
- return head;
- }
- ListNode* reverseBetween(ListNode* head, int m, int n) {
- if(head == nullptr || head->next == nullptr)
- return head;
- ListNode* q = nullptr,*p = head;
- for(int i = 0; i < m - 1; i++) {
- q = p;
- p = p->next;
- }
- //此时p指向第m个节点,q指向m前一个节点
- ListNode* end = p;//end用来指向逆序后的尾节点
- ListNode* pPre = p,*next = nullptr;
- p = p->next;
- for(int i = m + 1; i <= n; ++i){
- next = p->next;
- p->next = pPre;
- pPre = p;
- p = next;
- }
- end->next = p;//此时的p节点指向的是第n + 1个节点
- if(q){//注意q节点可能为空
- q->next = pPre;
- }else{
- head = pPre;
- }
- return head;
- // write code here
- }
最后,写文不易,不收藏也请给个赞,谢谢亲~!
(本文仅供学习时参考,如有错误,纯属作者技术不到位,不足之处请多指教,谢谢)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。