具体地,设当前链表的左端点为left,右端点 right,包含关系为[左闭右开),即 left 包含在链表中而right 不包含在链表中。我们希望快速地找出链表的中位数节点mid。
- 为什么要设定「左闭右开」的关系?
由于题目中给定的链表为单向链表,访问后继元素十分容易,但无法直接访问前驱元素。因此在找出链表的中位数节点mid 之后,如果设定「左闭右开」的关系,我们就可以直接用 (left,mid) 以及(mid->next,right) 来表示左右子树对应的列表了。并且,初始的列表也可以用 (head,null) 方便地进行表示,其中null 表示空节点。
- 初始时,快指针fast 和慢指针slow 均指向链表的左端点left。
struct ListNode* getMidian(struct ListNode* left, struct ListNode* right){
struct ListNode* fast = left;
struct ListNode* slow = left;
- 我们将快指针 fast 向右移动两次的同时,将慢指针slow 向右移动一次,直到快指针到达边界(即快指针到达右端点或快指针的下一个节点是右端点)。此时,慢指针对应的元素就是中位数。
while(fast != NULL && fast->next != NULL){
fast = fast->next;
fast = fast->next;
slow = slow->next;
}
return slow;