反转链表Ⅱ问题

实现要求:给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

例如下图:

输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]

例示2:

输入:head = [5], left = 1, right = 1
输出:[5]

反转链表问题的实现核心是利用 头插法 实现单链表来实现链表的逆置。

实现代码:

struct ListNode* reverseBetween(struct ListNode* head, int left, int right) {

   if(head==NULL||left==right){  //当链表为空或者只包含一个元素的时候直接返回链表

    return head;

   }

   struct ListNode dummy;     //定义哑结点,对于哑结点的定义我已经在前面的反转字符串问题文章中有过介绍

   dummy.next=head;

   struct ListNode *pre=&dummy;  

   // 定位到left的前躯结点,实现头插法的关键步骤之一就是找到要插入所要插入元素的头插结点,由于链表的独特构造因此要想找到前驱结点只能逐个遍历

   for(int i=0;i<left-1;i++){

    pre=pre->next;

   }

//pre是要插入位置的前驱结点,cur是当前结点是位于所要进行插入操作元素的前驱结点,nex是指当前要插入的结点

   struct ListNode *cur=pre->next;

   //头插法的实现过程

   for(int i=0;i<right-left;i++){

    struct ListNode *nex=cur->next;  //更新nex结点,指向要插入的元素

    cur->next=nex->next;    

    nex->next=pre->next;

    pre->next=nex;

   }       

//这里有一个易错点:   对于头插法 nex->next=pre->next 这句代码是否可以换成nex->next=cur呢?答案是不能,因为cur和·pre->next 在循环中不总是相等的。

例如:链表为1->2->3->4->5,反转区间为left=2 ,right=4(即反转2->3->4)

循环之前的cur是2,pre是1,nex是3(所在位置)

第一次循环,就是把3插入1,2之间,链表变为1->3->2->4->5,此时pre->next已更新为3,但是cur依然为2,要是再进行第二次循环,那么要把4,插入1,3之间,要是代码为nex->next=cur,会导致结点3的消失,链表变为:1->4->2->5。因此代码的逻辑漏洞主要在于没有考虑到cur在后续循环中是保持不变的,只是考虑了第一次循环cur=pre->next的特殊情况。

return dummy.next;  //返回逆转后的链表

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值