力扣题部分:
24. 两两交换链表中的节点
题目链接:. - 力扣(LeetCode)
思路:
有点难讲了,直接上图:
在图中1-3这样一个交换的流程中,发生交换的是步骤1中的p2和p3两个结点,如果p1是头节点的话这个流程无法实现,就要为这种情况专门再打一段代码,但是通过创建虚拟头节点在p1这个位置就可以将两种交换合并成一段代码,减少代码量。记得每次交换之后的边界细节判断,其他就没什么问题了。
代码实现:
19.删除链表的倒数第N个节点
题目链接:. - 力扣(LeetCode)
思路(双指针):
创造两个指针fast和slow(初始为都head),然后让fast先走N步,然后两个指针一起走直到fast后一个是末尾的NULL,此时刚好slow是要删除的前一个结点,然后删除操作就好了。
代码实现:
面试题 02.07. 链表相交
题目链接:. - 力扣(LeetCode)
思路:
先计算两个链表的长度差d,然后创建两个指针(初始为两链表头结点),让长的链表的头节点结点指针先走d步,之后对两个指针进行判断是否指向一个区域,如果是就找到了,如果不是就一直往下找到最后找不到return NULL。
代码实现:
142.环形链表II
题目链接: . - 力扣(LeetCode)
思路(双指针法):
首先通过两个指针p1和p2(初始都为链表头结点)每次p1走两步,p2走一步,每次走完判断是否指向一个区域,通过简单的数学知识可以得到如果有环的话两指针一定会再环内相遇。然后我们可以通过下图建立等式关系:
由相遇可得 -> 2 * ( x + y ) = x + y + n ( y + z )。
我们的目的是求x,所以由上式可得 x = ( n - 1 ) * ( y + z ) + z( n > 0 );
这式子乍一看好像没什么用,但是如果 n = 1 时 式子可以简化为 x = z。
x = z 又说明了什么呢?
如果相遇后我再从头开始创建第三个指针p3,当p2和p3走若干步后,两指针会指向一个区域。 这时我们发现:因为 x = z,l两者指向的区域刚好是入口结点。
可能又有人问,如果n != 1该怎么办呢?
有意思的来了——按照同样的操作,两指针仍然会在入口结点相遇。只不过这时,p2会先走n - 1圈的环形而已,不会影响两指针在入口结点相遇的结果。
代码实现:
链表总结:
通过这两天对链表的学习,我掌握了链表的基本操作,反转和两两交换链表元素的流程,查询链表倒数第x个的元素操作,判断带环链表以及确定环入口位置的方法。总的来说,链表题确实会相比数组难想一点,但是如果掌握了正确的思路题目也能迎刃而解。