快慢指针法 :ListNode fast = head,fast每次走两步,ListNode slow = head,slow每次走一步,当fast走完的时候slow刚好走一半。(因为奇数,偶数一半不同)
所以要对长度为奇数偶数分别讨论
Odd
N1 --> N2 --> N3 --> N4 --> N5 --> null
slow
fast
N1 --> N2 --> N3 --> N4 --> N5 --> null
slow
fast
N1 --> N2 --> N3 --> N4 --> N5 --> null
slow
fast
stop condition : fast.next == null
Even
N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> null
slow
fast
N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> null
slow
fast
N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> null
slow
fast
stop condition : fast.next.next == null
循环条件:fast.next != null && fast.next.next != null
这里有两点需要注意:
1.循环条件和stop condition相反,stop condition为(fast.next == null || fast.next.next == null)
(a || b)取反为(否a && 否b)
2.fast.next != null && fast.next.next != null 中两个条件不能交换顺序.
如果想要访问fast.next.next,必须要保证fast.next != null && fast.next.next != null
如果fast.next.next在前的话,当fast.next为空时,这里会报错空指针异常(java逻辑运算的短路效应)
public ListNode findMiddleNode(ListNode head){
// corner case
if (head == null) {
return null;
}
ListNode slow = head;
ListNode fast = head;
while (fast.next != null && fast.next.next != null) {
slow = slow.next; // slow每次跳一步
fast = fast.next.next; // fast每次跳两步
}
return slow
}
扩展问题,如果是偶数要求找到右边的中间值呢??
还是利用上边的方法分析,最后一步情况如下:
N1 --> N2 --> N3 --> N4 --> N5 --> N6 --> null
slow
fast
stop condition : fast == null
结合奇数的stop condition(fast.next == null),总的stop condition为(fast == null || fast.next == null)
循环条件:fast != null && fast.next != null