浅谈双指针技巧(三)利用快慢指针,查找链表中指定位置节点
作者:互联网
前面两篇文章主要介绍了,快慢指针在链表环中的应用。除此之外,我们还常常利用快慢指针来查找单向链表中指定位置的节点。
常见的经典题目有:
1、查找倒数i位置的的节点
2、查找中间节点
我们依次来看
一、查找快慢指针查找单链表中位于倒数第i个位置的元素
力扣 剑指 Offer 22. 链表中倒数第k个节点 (https://leetcode.cn/problems/lian-biao-zhong-dao-shu-di-kge-jie-dian-lcof/)
如果没有提前做过准备,想要解决类似问题,只能通过缓存等方式来解决。但是通过快慢指针,可以很巧妙的解决该问题。
思路是这样的:(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )
快慢指针同时指向head节点。接着慢指针不动,快指针向前移动i步。之后快慢指针同速前移动。直至快指针先到终点,此时慢指针,所处的位置就是倒数第i个节点的位置。
就像下图,假设右侧小人先跑40m,随后两者同速前进,则左侧小人距离右侧小人始终为40m。这样当右侧小人到达终点时,左侧小人的位置恰好为倒数40m处:
代码也很简单:
1 public ListNode getKthFromEnd(ListNode head, int k) { 2 ListNode fast = head; 3 ListNode tail = head; 4 for (int i = 0; i < k-1; i++) { 5 fast = fast.next; 6 } 7 while (fast.next != null) { 8 fast = fast.next; 9 tail = tail.next; 10 } 11 return tail; 12 }
这个场景其实除了双指针的解法,还可以通过递归出栈的方式解决,感兴趣的同学可以自己想想
二、查找链表中间位置的节点
力扣 876. 链表的中间结点 (https://leetcode.cn/problems/middle-of-the-linked-list/)
此题与上题类似,仍然可以采用快慢指针的形式。
区别是不再同速保持固定距离,而是快指针每次走两步,慢指针走一步。
这样假设快指针遍历了2N个节点,慢指针就是便宜了N个节点。
如果你自己考虑这个问题,你会发现事情没有这么简单:
这里会涉及到两个问题:(防盗连接:本文首发自http://www.cnblogs.com/jilodream/ )
1、链表长度是不是偶数。
2、链表如果是偶数,那么中间节点应该是中间位置左侧节点 还是右侧节点。
如果链表长度奇数的话,那么要注意快指针最后一次移动是不能走两步的。
如果链表长度是偶数的话,我们取中间位置的右侧节点。代码如下:
1 public ListNode middleNode(ListNode head) { 2 ListNode fast = head; 3 ListNode low = head; 4 while (true) { 5 if (fast.next == null) { 6 return low; 7 } 8 low = low.next; 9 fast = fast.next; 10 if (fast.next != null) { 11 fast = fast.next; 12 } 13 } 14 }
细想一下,这种思路其实除了可以找到中间节点位置,还可以找到1/3处节点位置,1/5处节点位置。
标签:ListNode,浅谈,fast,next,链表,节点,指针 来源: https://www.cnblogs.com/jilodream/p/16672026.html