本文已参与「新人创作礼」活动,一起开启掘金创作之路。
题目
给定一个链表,返回中点,如果是偶数,就返回下中点。
思路
这道题我们一般就是遍历一遍,然后看一下有多少个元素,然后除2就可以知道中点在哪了,但是我们还有一个很巧的方法,那就是快慢指针的方法。快指针每次走两步,慢指针每次走一步,最后等快指针为空的时候或者快指针的next为空,慢指针指向的位置就是中点
举例
1 -> 2 -> 3 -> 4 -> 5 -> next
上面就是需要查询中点的链表,然后我们定义两个指针,一个快一个慢,然后我们就开始
一开始fast指针指向1,slow指针也指向1
第一次,fast走两步到达3,slow走一步走到2
第二次,fast走两步到达5,slow走一步走到3
这个时候我们发现,fast的next为空,这个时候我们就返回slow。
代码
节点类代码
public static class Node {
public int value;
public Node next;
public Node(int v) {
value = v;
}
}
先提供节点的类
函数实现代码
public static Node findMid(Node head) {
if (head == null || head.next == null || head.next.next == null) {
return head;
}
// 链表有3个点或以上
Node slow = head;
Node fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next.next;
}
return slow;
}
演变
我们这边求解的是下中点,那我们怎么解决求解上中点呢?我们可以让fast先走是不是可以解决这个问题呢?
其实是不行的,因为先走的话,奇数的时候会变样,我们真正改的地方其实是判断的地方。
fast != null && fast.next != null
这个是我们现在的判断条件,
我们可以改成
fast.next != null && fast.next.next != null
这个就是我们改之后的判断条件。
为什么改判断条件可以,但是让fast先走不行呢?
如果是先走的话,我们判断fast.next的时候其实又往后面走了一步,这样是不行的。这样就会导致奇数的时候会少一个的情况。