题目描述
找到一个链表的中间节点
如果中间节点有两个,取右边的那个
解法
核心思想:快慢指针找中点
使用两个指针,慢指针每次前进一个节点,快指针每次前进两个节点,当快指针指向链表末尾时,慢指针正好指向中点
(之前有一个快慢指针找循环,这里有一个快慢指针找中点,快慢指针可真好用)
code如下:
class Solution {
public ListNode middleNode(ListNode head) {
if (head == null || head.next == null) {
return head;
}
ListNode slow = head;
ListNode fast = head;
while (fast != null && fast.next != null) {
slow = slow.next;
fast = fast.next;
fast = fast.next;
}
return slow;
}
}
拓展
同样是一道链表题,给定链表head和一个整数n,链表长度未知,要求返回链表中间的n个节点
例如:
有链表1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9
,给定n = 3
,则需要返回节点[4, 5, 6]
快慢指针的思路也可以应用于这一题,只是慢指针行为稍作改变。在快指针进行移动的同时,慢指针并非从一开始就跟着移动,而是要等到快指针移动的距离超过了n / 2
之后才开始移动
public List<Node> getNnodes(Node head, int n) {
if (head == null || n <= 0) {
return new ArrayList<Node>(0);
}
Node slow = head;
Node fast = head;
int len = 1;
while (fast != null && fast.next != null) {
if (len > (n / 2)) {
slow = slow.next;
}
len += 2;
fast = fast.next;
fast = fast.next;
}
if (fast == null) {
len++;
}
// capacity的作用是解决n比链表长度更大时的问题
int capacity = Math.min(len, n);
List<Node> res = new ArrayList<>(capacity);
for (int i = 0; i < capacity; ++i) {
res.add(slow);
slow = slow.next;
}
return res;
}