链表相交:
题意:
给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。注意,函数返回结果后,链表必须 保持其原始结构 。
思路:
首先要注意一点是,这里的相交节点不是节点的值相同,而是指向节点的指针相同,当有一个节点相同是,那它后面的所有指针所指向的节点也就相同了,所以我们这里只找到第一个节点并返回就可以。
那后面的指针所指向的节点相同的话,那么一定要保证节点的数目是相同的,所以我们要让两个链表尾部对齐,保证从相交结点开始,一直到尾部的数量是相等的。
要让尾部对齐,就是让节点数量多的链表的指向头结点的指针后移两链表节点数目的差值,并且以指向的节点为头节点。这样尾部就对齐了。并且指针都处于距离尾部相等距离的位置。
随后指针开始遍历,直到找到相同节点,如果没找到的话,那么返回null.
注意点:
当我们求节点数目的差值时,很难保证哪个链表的节点数目多,分开求解的话,所有步骤需要写两遍,比较繁琐。此时我们可以让链表a的数目始终是多的一方,如果a的数目少,那就交换a和b的数目,和头节点指针。
代码如下:
环形链表:
题意: 给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
为了表示给定链表中的环,使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。 如果 pos 是 -1,则在该链表中没有环。
说明:不允许修改给定的链表。
结论: head节点的指针和fast 和slow相遇位置的指针,他们两个指针会同时到达环形链表的入口点。如果要看详细解析,移步代码随想录:环形链表(其中fast是快指针,它每走一步跨越两个节点,slow是慢指针,每一步跨越一个节点)
具体做法:
当我们清楚这个结论之后,我们要做的就是先找到slow,fast指针交互的位置。找到位置之后,我们可以新定义指针,一个指向头节点,一个指向当前两指针交汇的位置。让他们同时开始后移,直到两指针相等时,结束。
注意点:
我们需要考虑没有环形链表时怎么办,所以fast和slow相等的条件可以写在while循环里,否则,如果while循环的条件是slow!=fast ,没有环形的时候,那么就会出现死循环。所以我们while循环条件只需要写fast->next!=null ,fast->next->next!=null 就可以了。因为fast每走一步跨越两格,所以需要写这些。
代码:
19.删除链表的倒数第n个节点
难点:
我们不清楚链表节点的个数,所以我们没办法知道要删除的节点所在的从前向后的位置。
解决方法:
如果要删除倒数第n个节点,先让fast和slow都指向虚拟头节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的下一个节点即可
知道解决方法这道题就迎刃而解,因为要删除的节点就是slow所指向的下一个节点。
代码如下:
24.两两交换链表中的节点
小问题:
题只是交换链表中的节点,但是有一个小问题是头节点的位置会发生变化,所以必须前两个节点交换和后面的节点交换分开,但是有简单的方法就是设置虚拟头节点,让头节点永远是虚拟头节点的下一个。
思路:
先交换前两个节点,之后cur指针不断后移两位置,知道cur->next!=null,并且cur->next->next!=null,(因为一次性后移两个节点,而且我们是会关联到cur->next->next->next, 所以想不发生错误,一定要让->bext->next不为空) (我们要注意cur是交换结点第一个的前一个结点,如果要交换1 2,那么cur指向的就是0.)
注意:
1.一定要画图一定要画图一定要画图!!!!
2.里面的temp1,temp2是临时节点,为了防止要保存的数据丢失。
代码如下: