第一题:
>思路一:
1.第一遍遍历链表,直到找到尾结束第一次遍历,遍历的过程中记录链表长度。定义长度为k。
2.确定中间是第几个节点,计算是k/2+1根据题目要求。
3.再一次去遍历我们的数组,找到中间节点,返回节点。
>思路二:
使用了一个快慢指针的思想。
1.定义一个慢指针和一个快指针。
2.v快=2v慢,同起到,时间时间是时刻相同。
3.x快=2x慢。当快指针走到尾的时候慢指针才走到中间。
struct ListNode* middleNode(struct ListNode* head){
struct ListNode* quic=head,*slow=head;
//判断奇数,判断偶数.两个条件满足一个就结束。
while((quic) && (quic->next))
{
slow=slow->next;
quic=quic->next->next;
}
return slow;
}
第二题:
>思路一
1.第一遍遍历链表,直到找到尾结束第一次遍历,遍历的过程中记录链表长度。定义长度为n
2.确定倒数第k个是正数第n-k个
3.再一次去遍历我们的数组,找到倒数第k个,返回节点。
>思路二
1.相对距离的使用,定义一个前面的指针和后指针,初始都是在头节点。
2.先循环遍历后指针k让后指针向后移动k次,前后指针再用相同的速度向后同时移动,当后指针为空时就结束,这个时候的前指针就是倒数第k个节点。
3.特殊情况:
1.一共k个节点倒数第k个就是第一个节点。循环结束n1,ffastNULL;判断n1返回头就可以。
2.节点为空,链表没有数据直接返回空在开始就判断。
3,n0和fast!=NULL,说明我们的接下来的双指针移动没有问题可以正常进行。
struct ListNode* FindKthToTail(struct ListNode* pListHead, int k ) {
// write code here
//对于一个链表来说应该开始就判断是否为空链表。
if(pListHead==NULL)
{
return NULL;
}
struct ListNode* fast=pListHead,*slow=pListHead;
int n=k;
//位置差搞出来
while(n&&fast->next!=NULL)
{
fast=fast->next;
n--;
}
//一共只有k个节点的情况,倒数第k个就是头
if(n==1)
{
return pListHead;
}
//循环找第k个节点的时候没有超出链表的范围,前后的指针都是正常的。
if(n==0)
{
while(fast!=NULL)
{
slow=slow->next;
fast=fast->next;
}
return slow;
}
return NULL;
}