代码随想录训练营第四天

专题:链表

题目:两两交换链表中的节点

给定一个链表,两两交换其中相邻的节点,并返回交换后的链表。

你不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

例如:

 

 

 

题目分析

 要两两交换链表中的结点,怎么操作呢?我们使用cur指向虚拟头节点,对虚拟头节点的后两个结点进行翻转操作。然后cur往后移动两个位置,继续操作当前结点的后两个结点。依次循换直到全部的结点翻转过来直到cur的->next或cur->next->next=NULL循环结束(如果cur->next为空的话,说明cur就是最后一个结点,不要在翻转,如果cur->next->next =nullptrd的话说明cur后面只有一个结点了,也不用翻转了)。具体操作:先得用临时指针temp 和temp1保存 head 和 下下一结点,因为要改变dummyhead->next 的指向 不保存head的话,就找不到了。因为要改变下一结点的指向,不保存下下一结点指针的话,也就找不见了。保存了之后。然后依照①②③的顺序去执行。然后更新cur=cur->next->next;

细节注意:

注意:

使用虚拟头结点,就可以满足对链表每个结点的统一操作;

判断条件是链表结点有后两个结点才会满足翻转的条件。怎么判断呢?(cur->next != nullptr || cur->next->next != nullptr) ; 

在执行翻转操作时,铭记一旦执行一个翻转的步奏,那么链表结点就会产生一次变化。所以要根据最新的链表信息来写后面的语句。

代码实现:

题目:删除链表的倒数第N个结点

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。 

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

输入:head = [1], n = 1 输出:[ ]

题目分析:

快慢指针法:快慢指针fast slow 指向head;先让快指针走到第n个结点。然后快指针不为空的情况下,快慢指针都往后走,直到快指针指向空。此时慢指针指向的就是,倒数第n个结点的前一个结点,然后操作倒数第n个结点的前一个结点,指向倒数第n个结点的下一个结点。然后完成了删除倒数第n个结点的操作。

细节注意

这个题目,让我第一次发现,编译器是一个老实人,不管你用心写的,还是随意写的,编译器就只会老老实实的根据你的代码去做事情。所以一旦发现编译器,没执行通过。不要怀疑老实本分的编译器,好好看看自己的代码,找到问题,修改正确。编译器就能通过。

注意事项:链表的节点的把握,快慢指针指向dummyhead 还是 dummyhead->next.怎么设计才能让fast走到null的同时,slow刚好到倒数第n个结点的前一个结点位置。这个必须明白。

如果 fast slow 都指向 dummyhead 那么 此时判断条件就是 fast->next != nullptr,fast=fast->next;slow=slow->next;

如果 slow 指向 dummyhead ,fast 指向 dummyhead->next ;那么 此时判断条件就是 fast!= nullptr,fast=fast->next;slow=slow->next;

记住要让fast先走n步;

代码实现

 题目:链表相交

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

 题目分析:

首先计算两个链表的长度,长的减短的,算出个数差,然后定义两个指针,分别指向这两个链表。先让长的链表的指针,往后走他两的差的步子,然后他两一起往后走,如果能遇到即他两个指针相等,说明就找到了相遇的地方。如果指针一直都不相等,说明没有相交的结点。

细节注意:

思想简单,但是要

一定注意,在统计完链表长度之后,一定要让cura,curb指向原来的链表头。

之后交换的时候,目的就是为了,明确让cura去指向长的链表,curb去指向短的链表。方便后面减法操作。

代码实现:

 题目:循环链表

题意: 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。

为了表示给定链表中的环,使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。

题目解析

首先你要深刻理解,原理!!!

fast指针一次走两步的条件是(fast!=nullptr && fast->next != nullptr)保证了这个条件,那么fast->next->next这个位置,可以有值,也可以是NULL。没关系,都可以让fast去指向这个位置即 fast-->next = fast->next->nextr->next;

两个指针fast 和 slow 都指向head节点,然后fast一次走两步,slow一次走一步。然后如果有环的话,fast ,slow 肯定就相遇了。因为如果有环的话,fast最后在环里面一次走两步,slow在环里面一次走一步,那么相当于slow在环里面不动,fast一次走一步,那么fast肯定可以和slow相遇。一旦相遇就说明肯定有环。

此时完成了是否有环的判断!!!!!!!

还有就是如何寻找环的入口????

根据公式计算,最终得到当n=1时,x=z;即head到环入口的距离等于fast和slow相遇点到环入口的距离。根据这个条件,我们设置两个指针index1,index2.一个指向head,一个指向fast,slow相遇点。然后while(index1 != index2)就都往后走一步,直到index1 = index2 返回index2;也就是环的入口。

 由题意得:2(x+y) = x+y+n(z+y)

           得: x+y =n(z+y)

                   x = nz +(n-1)y

           当n=1时,得 x=z;

这就意味着,从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点

代码实现:

 一个关键点:对于index1和index2,这个点。要在if条件里面就去定义它,执行它。在一个大括号里面定义的变量,在大口号外面使用不了????对的!!认真思考!!!

录友告诉我,大括号里面定义的变量,出了大括号就不能使用了,是吧。

答:变量只在定义及“}"之前有效。  一起学习,就是快乐!!!!

 

今天,在训练营里面提问,录友回答了我的疑问,让人感觉很爽!!!

一起学习是一件狠狠快乐的事情!!!!!!!!!!!!1

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值