1.两两交换链表中的结点(力扣)
题目中明确规定的一点就是不让你交换值,难受~
所以只能想办法交换节点。在交换的时候最好把所有的结点都变为非首元结点进行操作,所以在链表的前面定义一个虚拟头节点。然后考虑几种特殊情况,一种是节点数目为奇数的时候,最后一个节点就不需要再进行交换,结束条件是current->next!=NULL;另外一种是结点数目为偶数的时候,最后一对结点交换完毕后停止,结束条件又变成了current!=NULL。
基于上述考虑,所以直接再while里面将两种情况都考虑即可。然后就是交换结点的操作,关键在于顺序。以最初两个结点为例,定义两个指针temp和temp1分别指向虚拟头节点和第一个结点,然后进行如下操作:temp->next=temp1->next(0->2);temp1->next=temp->next->next(1->3);temp->next->next=temp1(2->1);temp=temp1;temp1=temp->next(这样就完成了遍历)。
2 .删除链表的倒数第n个结点(力扣)
要删除第n个结点,我们就必须找到第n-1个结点对其进行操作来删除。由于找的是倒数第n个结点,所以再不先遍历链表获取链表结点个数的前提下,利用快慢指针对倒数第n个结点进行定位。但如果需要删除的元素为第一个,操作又会变得复杂,所以依然定义一个虚拟头节点进行操作。让快指针指向虚拟头节点,让慢指针指向首元结点,先让快指针移动n次,再让快慢指针一起移动直到快指针为空,此时慢指针就定位到了倒数第(n+1)个结点的位置,进行删除就完成了。
3.面试题02.07 链表相交(力扣)
这个题最恶心的不是有多复杂有多绕,最恶心的是它的题目描述就是答辩,绕进去了就G了。
通过观察题目给出的例子不难发现,只要尾部对齐,第一个相同结点的即时相交的第一个元素(注意:并不是值相等而是指针相等 指向同一个结点 反例详见题目例1)。所以需要先获取两个链表的长度,然后让长度较长的一个链表指针往前移动至剩下链表长度与另一个链表相同的位置,对两个链表进行遍历,直至结点相等。
4.环形链表Ⅱ(力扣)
这个题分两步:一是判断环是否存在,二是判断环的起点。
在判断环是否存在的时候,只需要用一个指针遍历看它是否能走出去(但是如果走不出去就变成了死循环),所以就不能只用一个指针,需要两个指针同时运动,而运动的条件就是快指针及它的下一个指针不为空。对于慢指针每次走一格,而快指针每次走两格,无论这个环多大,慢指针在进入环的第一圈一定会被快指针追上(因为慢指针走一圈的事件快指针可以走两圈 所以慢指针的第一圈一定走不完)。用一个图来解释其中的数学关系:(图片是代码随想录的)
那么当快慢指针相遇时路程满足:2(x+y)=x+y+n(y+z)----->x=(n-1)(y+z)+z
当快慢指针相遇的时候,只需要在快指针和head处同时用指针进行移动,相遇的地方就会是起点