【21天考研算法带刷leetcode-92】必会!反转链表的两道精彩(7/21)

线性表的部分就更到前面了,还有很多精彩的内容后面再补充进去吧,后面将会写链表、树、图,链表的第一部分:链表逆置是非常非常常考的内容,大家一定要重视呀!!

一、leetcode 206 简单的链表逆置

把一个链表逆置有两种思路,一种是不带头结点的,另一种使用虚拟头结点

其实两种算法本质没有区别,只是理解起来的思路不太一样,如果使用头结点,那我们可以按照头插法的思路去想,每次将这个结点从链表中取下来,再插入到虚拟头结点后面,那么这个循环的过程需要几步呢? 答:四步

while(p!=NULL){

temp=p->next;//暂存后面的链表,防止弄没

p->next-newhead->next ;//我们知道 插入将一个结点插入到一个链表中,要先修改后面的指针

newhead->next=p;//插入的第二步,成功建立联系

p=temp;//暂存了就要再赋值回来

}

那么用不构建头结点,就用指针如何来实现呢?本质还是一样的,四步,但是理解起来不太好想,设置pre指针的初值是NULL,这个指针永远代表逆置了的链表的头结点,每次操作完都要对其更新(实际上进行的逻辑上的前移)。比如pre=cur; 当然刚开始pre是NULL,工作指针的next也就是NULL了。

1 ->2->3->4的例子来演示

temp=2->3->4                      第二次 temp=3->4;        `        第三次 temp=4

1->next=NULL;                          2->next=1->NULL;                        3->next=2->1->NULL

pre=1->NULL;                            pre=2->1NULL;                                pre=3->2>1

cur=2->3->4                                cur=3->4                                             cur=4;


struct ListNode* reverseList(struct ListNode* head){
    struct ListNode* cur=head;
    struct ListNode* pre=NULL;
    struct ListNode* temp=NULL;
    while(cur){
        temp=cur->next;
        cur->next=pre;//双指针思路 相当于让current上pre的列上去,产生关联
        pre=cur;//pre指针代表的是反向链表的头结点,先把cur赋值过来,实际上实现了前移
        cur=temp;//temp是为了让cur实现了后移
    }
    return pre;
}

二、leetcode 92反转部分链表

这个过程实际上就是,三大步 先把要反转的链表拆下来,然后将其反转,再将其插回到原链表中,因此前两个while循环是为了确定 链表拆下来的位置。再反转链表过程和插回中有两个注意事项写在了代码段中,很欢迎大家一起来讨论。


struct ListNode* reverseBetween(struct ListNode* head, int left, int right){
    struct ListNode*  p=head;
    struct ListNode*pre_i=NULL;
    int i=left;
    struct ListNode* after_j=head;
    while(i>1){
        pre_i=p;
        p=p->next; //pre_i是i之前的第一个元素
        i--;
    }
    int j=right;
    while(j>0){
        after_j==after_j=->next;//after_j=NULL;
        j--;  //after_j=是j以后的第一个元素
    }
//以下为反转链表的部分
    struct ListNode*pre=after_j=;//这里不能写NULL 不然会丢掉j以后的元素
    while(p!=NULL&&right>=left){
        struct ListNode* temp=NULL;
        temp=p->next;
        p->next=pre;
        pre=p;
        p=temp;
        right--;
    }
    if(pre_i==NULL) return pre; //这是从头开始逆置的情况直接返回,因为pre——i为空
    pre_i->next=pre;
    return head;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

积极向上的11

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值