题目
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
思路1:我们可以遍历链表,记录链表的节点个数,这样我们就知道我们想找的中间的那个链表的位置。这种方法就不贴代码了,提供一种思路而已(好吧,实际上我没写这种hhhh)
思路2:我们知道,链表不支持随机访问,只支持顺序访问,也就是只能从头开始遍历才能找到我们想要的节点。我们可以将链表放到Arraylist中,通过索引下标来返回中间节点。
public ListNode middleNode(ListNode head) {
List<ListNode> list = new ArrayList<>();
while(head != null){
list.add(head);
head = head.next;
}
int size;
if(list.size()%2 ==0){
size = list.size()/2;
}else {
size = (list.size()-1)/2;
}
return list.get(size);
}
思路三:使用双指针,一块一慢,快指针一次走两格,慢指针一次走一格,如果快指针的next或者next.next为空,我们就认为此时的慢指针的后继就是中间节点了。
public ListNode middleNode1(ListNode head) {
// 先讨论特殊情况,即只有一个节点,那中间节点就是它本身
if(head.next == null){
return head;
}
ListNode slow = head;
ListNode fast = head.next;
while(fast.next!=null && fast.next.next!=null){
slow = slow.next;
fast = fast.next.next;
}
// 由于循环条件是快指针的后继为空(主要是为了防止空指针异常)
// 所以理论上慢指针的后一个节点才是我们想要的中间节点
return slow.next;
}