链表内指定区间反转(C和C++实现)

描述

将一个节点数为 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)

C语言实现

首先找到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;
}

C++

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
    }

最后,写文不易,不收藏也请给个赞,谢谢亲~! 

(本文仅供学习时参考,如有错误,纯属作者技术不到位,不足之处请多指教,谢谢)

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值