1. 方法一-单链表,两次遍历法
(1)算法思想:遍历一遍整个链表,求得链表的长度len
后,再从头遍历链表len/2
遍,即可到达链表的中点处。
(2)代码:
public ListNode findMid(ListNode head) {
int len = 0;
ListNode curr = head;
while (curr != null) {
len++;
curr = curr.next;
}
curr = head;
// 当有两个中间节点时(链表偶数情况),要求返回第二个节点
for (int i = 0; i < len / 2; i++) { // 循环len/2次
curr = curr.next;
}
// 当有两个中间节点时(链表偶数情况),要求返回第一个节点
for (int i = 0; i < (len - 1) / 2; i++) { // 循环(len-1)/2次
curr = curr.next;
}
return curr;
}
2. 方法二-快慢指针法
(1)算法思想:维护一个快指针和一个慢指针,快指针一次移动2步,慢指针一次移动1步,当快指针到达链表尾部的时候,慢指针刚好到达中点位置。
(2)代码:
public ListNode findMid(ListNode head) {
ListNode slow = head, fast = head;
// 存在两个中间节点的情况,需要返回第二个中间节点
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
// 存在两个中间节点的情况,需要返回第一个中间节点
while (fast.next != null && fast.next.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
ps:存在两个中间节点的情况,如果搞不清楚边界的处理,画一个5个节点的链表和一个6个节点的链表就明白了。