解法一 单指针法
给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。
struct ListNode* middleNode(struct ListNode* head){
struct ListNode *p;
int len=0;
p=head;
while(p!=NULL){//遍历链表获得链表长度
++len;//计算链表长度
p=p->next;//指向链表中下一个元素
}
int k=0;
p=head;//这里再重新声明一次p=head,因为第一次的时候p已经到最后一个节点了,所以要让p回去一次
while(k<len/2){
++k;
p=p->next;
}
return p;
}
解法二 双指针法
struct ListNode* middleNode(struct ListNode* head){
struct ListNode *slow = head, *fast = head;//定义两个结构体指针
while ((fast != NULL) && (fast->next != NULL)) {//结构体遍历
fast = fast->next->next;//fast所指目标head的next的next,即fast指针移动两次
slow = slow->next;//slow所指目标head的next,即slow指针移动一次
}
return slow;
}
在head出发,A比B快n个结点。这样当A遍历完整个链表,到链表末尾时,B刚好慢了n个结点,则B对应的下一个结点就是我们要删除的那一个结点。我们直接让B略过下一个指针到下下个指针,这样就实现了head走指针的时候略过要删除的那一个结点,最后返回head