问题描述
给定一个带有头结点 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
示例 1:
输入:[1,2,3,4,5]
输出:此列表中的结点 3 (序列化形式:[3,4,5])
返回的结点值为 3 。 (测评系统对该结点序列化表述是 [3,4,5])。
注意,我们返回了一个 ListNode 类型的对象 ans,这样:
ans.val = 3, ans.next.val = 4, ans.next.next.val = 5, 以及 ans.next.next.next = NULL.
示例 2:
输入:[1,2,3,4,5,6]
输出:此列表中的结点 4 (序列化形式:[4,5,6])
由于该列表有两个中间结点,值分别为 3 和 4,我们返回第二个结点。
问题分析
方法1、求链表中间节点问题,即只需求出链表的长度,获得mid大小的时候分别对奇偶判断,然后获取中间节点即可。
方法2、设置两个指针,fast和slow指针,初始值为头结点,fast每次走两步,slow每次走一步。
java代码实现
方法一:
public ListNode middleNode(ListNode head) {
if(head == null){
return null;
}
if (head.next == null){
return head;
}
int cnt = 1; //链表长度
ListNode cur = head;
while (cur != null){
cur = cur.next;
cnt++;
}
int mid = 0; //中间节点
if (cnt % 2 != 0){ //为奇数
mid = (cnt - 1) / 2;
}else { //为偶数
mid = cnt / 2 - 1;
}
cur = head;
while (mid != 0){
cur = cur.next;
mid --;
}
return cur;
}
方法二、快慢指针
public ListNode middleNode(ListNode head) {
if(head == null){
return null;
}
if (head.next == null){
return head;
}
ListNode fast = head;
ListNode slow = head;
while (fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}