链表的面试题3找出中间节点

来来来,接着继续我们的第三道题 。

解法

暴力求解

快慢指针


 https://leetcode.cn/problems/middle-of-the-linked-list/submissions/

这道题的话,思路是非常明确的,就是让你找出我们这个所谓的中间节点并且输出。

那这道题我们就需要注意一些细节上的问题,或者说是对于整个链表结构的访问的理解要到位。

如果这道题放在顺序表上,那我们很容易就能根据下标来判断是否为中间节点。但是,问题就出在,链表是不能依据数组下标来访问的,那这道题我们很简单的思路就是,先得出链表长度,再定义变量值来求中间节点。那我把代码贴在下面。

暴力求解

typedef struct ListNode ListNode;
struct ListNode* middleNode(struct ListNode* head){
    ListNode* pcur = head;
    int count = 0;
    int ret=0;
    // 求链表的长度count
    while (pcur) {
        count++;
        pcur = pcur->next;
    }
    pcur=head;//重置pcur为头节点
    while(pcur&&ret<(count/2)){
        ret++;
        pcur=pcur->next;
    }
    return pcur;
}

快慢指针

那这道题应该放在第一道题的,因为这是非常好的一道题能看出我们的双指针法到底有多便捷。我们根据前两道题目也知道,双指针又叫快慢指针法,注定有一个指针走的快,有一个走得慢,我们根据走的快的指针和慢指针的差值的逻辑关系,来确定此时慢指针到底处于什么位置。

下面给大家放一张图表示一下快慢指针

从图中我们就能很容易的看到fast永远比slow快一步。这样做的好处是什么?我们在刚刚的暴力求解的时候,是不是要注意一个细节,那就是,我们的简单粗暴的代码,并不能同时涵盖奇数和偶数,需要分类讨论。而快慢指针就没有这样的麻烦,可以极大的缩短我们的时间复杂度,提高效率。

struct ListNode* middleNode(struct ListNode* head){
    struct ListNode *fast = head, *slow = head;
    while(fast && fast->next){
        slow = slow->next;
        fast = fast ->next ->next;
    }
    return slow;
}

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值