链表中的快慢双指针,用来找链表的中间节点。
这里分为2种情况:
- 1是链表节点数量是奇数个,中间节点正好把链表分为前后两半
- 2是链表节点数量是偶数个,中间节点的定义可以是中间两个的前一个或者后一个
如果链表节点是奇数个,或者偶数个,要求中间的前一个节点,代码就是一般的情况
可以这么记:fast跳2步,所以判断fast的next不为空且fast的next的next不为空
Java
public ListNode getMidNode(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
如果想要偶数个节点的中间第二个,需要修改一下while循环的条件
Java
public ListNode getMidNode(ListNode head) {
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
为什么会有这个区别?
为什么奇数个节点,无论哪一种,都正好在中间呢?
是因为指针移动之前就已经在头节点了,假设指针是快指针,移动两步,就到第3个节点了。(两种区别只是判断的条件不一样,都是移动2个位置)
所以一个奇数个节点的链表,排除头节点,正好要移动2的整数倍步数 而偶数个节点的链表,排除头节点,剩下奇数步数,可能没移动到结尾
如果没移动到结尾(慢指针在中间2个节点的第1个) 如果移动到结尾(慢指针在中间2个节点的第2个)
快慢指针用来找倒数第N个节点
快指针先走N步,慢指针和快指针同时走,快指针到头(null),慢指针在倒数N的位置
WARNING
⚠️注意这里
这里先走N步,需要理解为是节点的间隔N
快指针到头,其实是走到null节点,跟null节点间隔N的,是倒数第N个节点 ( 所以慢指针在倒数第N的位置 但是删除这个节点,需要找到N-1的位置 所以这里涉及一个技巧,fast是从head开始走,slow从虚拟头节点开始走 )
快慢指针用来找第一个共同节点(差和双指针)
较长链表长度为l1,较短链表长度为l2,差值为d = l1 - l2 快指针先走d步,而后快慢同时走,节点相同的就是第一个共同节点