1.题目
有一个单向非循环链表,请找到链表的中间节点,如果链表有两个中间节点,返回第二个中间节点。【要求】只遍历一遍链表
2.思路
只遍历一遍链表,我们想到的是快慢指针。先看一个数学问题:
a车的速度是b车的2倍,如果a车到达终点,b车是到达全程的一半。
类似的,我们让两个指针往前走,第一个指针速度是第二个指针速度的二倍,如果第一个指针到达终点,第二个指针就到达中间。
我们考虑特殊情况,如果有两个中间节点,那将会怎么样呢?
![](https://i-blog.csdnimg.cn/blog_migrate/ba8a9790415ca0f4f78d64c6815399d1.png)
很显然,它会到达第二个中间节点。
3.代码
/**
* Describe:
* User:lenovo
* Date:2023-01-05
* Time:22:57
*/
class Node {
int val;
Node next;
public Node() {
}
public Node(int val) {
this.val = val;
}
}
class MyLinkedList {
public Node head;
public MyLinkedList(Node head) {
this.head = head;
}
public MyLinkedList() {
}
}
public class Test {
public static Node findMidNode(MyLinkedList list){
//链表为空
if(list.head == null) {
return null;
}
Node fast = list.head;
Node slow = list.head;
while(fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
public static void main(String[] args) {
Node n1 = new Node(1);
Node n2 = new Node(2);
Node n3 = new Node(3);
Node n4 = new Node(4);
Node n5 = new Node(5);
Node n6 = new Node(1);
n1.next = n2;
n2.next = n3;
n3.next = n4;
n4.next = n5;
n5.next = n6;
MyLinkedList myLinkedList = new MyLinkedList(n1);
Node node = findMidNode(myLinkedList);
System.out.println(node.val);
}
}
如果链表为空,直接返回;
设置快慢指针,fast,slow,fast=null或者fast.next=null的时候停止循环(这两个条件不能调换位置,我们要先保证fast!=null才能保证下个判断条件不会报错),快指针走2步,慢指针走1步;
循环结束后,直接返回慢指针。