链表
获取链表的中间节点
看了一些博客,个不一致,有的代码实现是错误的,所以把自己想的记录下来。
有的时候:对于偶数个数的链表,我们需要获取链表的中间节点的偏左,有的时候偏右。所以具体情况需要具体分析。主要想法如下
leetcode
地址: 876
普通解法
先遍历一次,计算链表的长度,进而计算链表中间结点的下标(注意偶数结点的时候,得到的是中间的第二个结点),然后再遍历一次,来到所要求结点的位置
缺点
- 必须先遍历完整个链表,然后才可以「干正事」,再遍历到一半,找到中间结点
- 链表的长度很长的时候,这种方法之前的等待会很久
快慢指针
使用两个指针变量,刚开始都位于链表的第 1 个结点,一个永远一次只走 1 步,一个永远一次只走 2 步,一个在前,一个在后,同时走。这样当快指针走完的时候,慢指针就来到了链表的中间位置
需要注意:在处理偶数节点个数的链表的时候,需要注意最后中间节点落地的位置
- 希望中间节点处于左边,那么循环条件为:当前快指针的下一个结点和当前快指针的下下一个结点都非空
- 希望中间节点处于右边,那么循环条件为:当前快指针和当前快指针的下一个结点都非空
处于右半边
处于左半边
代码
/**
* 做左半边
*
* @param head
* @return
*/
public Node getMiddleNodeLeft(Node head) {
Node slow = head;
Node fast = head;
while (fast.next != null && fast.next.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}
/**
* 右半边
*
* @param head
* @return
*/
public Node getMiddleNodeRight(Node head) {
Node slow = head;
Node fast = head;
while (fast != null && fast.next != null) {
fast = fast.next.next;
slow = slow.next;
}
return slow;
}