leetcode 876.链表中间结点

链表中间结点

leetcode题目链接:876. 链表的中间结点
在这里插入图片描述

一、朴素解法

最直观的思路,因为不知道这个链表的长度,就先通过一次循环统计链表的长度len
之后第二次遍历,直到找到中间结点,输出

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */
 
struct ListNode* middleNode(struct ListNode* head){
    struct ListNode *p = head;
    int len = 0, t = 0;
    // 统计链表长度len
    while(p){
        len++;
        p = p->next;
    }
    p = head;
    while(1){
        if((t==((len-1)/2))&&(len%2!=0)){
            return p;
        }
        if((t==(len/2))&&(len%2==0)){
            return p;
        }
        p = p->next;
        t++;
    }
}
结果:

在这里插入图片描述

二、快慢指针

通过分析发现,第一次遍历几乎没做什么事,就是统计了一下链表的长度,当链表长度很长时,就会浪费大量的时间。
采用快慢指针,快指针一次走两步,慢指针一次走一步,这样当快指针走到链表结尾时,慢指针正好指向中间节点。

1. len = 2n

Eg. len = 4

第一步(初始状态)

快慢指针都指向第一个节点(头节点)
在这里插入图片描述

第二步

快指针前进两步,慢指针前进一步
在这里插入图片描述

第三步

快指针到达链表末尾,此时慢指针正好指向题目要求的偶数个数的第二个中间节点,结束循环,
结束条件: fast == NULL
在这里插入图片描述

2. len = 2n+1

Eg. len = 5

第一步 (初始状态)

在这里插入图片描述

第二步

快指针前进两步,慢指针前进一步
在这里插入图片描述

第三步

虽然此时快指针没有到达链表结尾,但是此时慢指针已经到达了链表中间,此时应该标记为结束标志结束循环,否则快指针去找NULL的next就会出错
判断条件: fast->next == NULL
在这里插入图片描述
因此可以得到两种情况下的结束条件是 fast && fast->next

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

在这里插入图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值