C语言中链表经典面试题目

这篇具有很好参考价值的文章主要介绍了C语言中链表经典面试题目。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

🐶博主主页:@ᰔᩚ. 一怀明月ꦿ 

❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C++

🔥座右铭:“不要等到什么都没有了,才下定决心去做”

🚀🚀🚀大家觉不错的话,就恳求大家点点关注,点点小爱心,指点指点🚀🚀🚀

 

目录

环形链表

环形链表 II


环形链表​​​​​​​

给你一个链表的头节点 head ,判断链表中是否有环。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

示例 1:

C语言中链表经典面试题目

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

C语言中链表经典面试题目

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

C语言中链表经典面试题目

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

提示:

  • 链表中节点的数目范围是 [0, 104]
  • -105 <= Node.val <= 105
  • pos 为 -1 或者链表中的一个 有效索引 。

进阶:你能用 O(1)(即,常量)内存解决此问题吗?

解题思路:

利用双指针的解法,一个慢指针slow,一个快指针fast,slow一次走一步,fast一次走两步,如果fast和slow相遇,说明链表带环,如果fast或fast->next为空,就说明链表不带环。

bool hasCycle(struct ListNode *head) 
{
    struct ListNode* slow=head;
    struct ListNode* fast=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)
        {
            return true;
        }
    }   
    return false; 
}

注意事项:

假设该链表带环
1.slow走一步,fast走两步,slow和fast一定会相遇吗?

2.slow走一步,fast走n(3,4,5……)步,slow和fast会相遇吗?

a.slow走一步,fast走两步,slow和fast一定会相遇吗?

结论:slow和fast一定会相遇

证明如下:

fast会先进入环,slow后进入环,假设slow进环时,slow与fast之间的距离是N,slow进环以后,fast开始追击slow,slow每走一步,fast走两步,它们之间的距离缩小1,追击过程中,,它们之间距离的变化:
N

N-1

N-2

...

2

1

0

当它们之间的距离为0的时候,说明slow和fast相遇了。即证明slow走一步,fast走两步,slow和fast一定会相遇。

b.slow走一步,fast走n(3,4,5……)步,slow和fast会相遇吗?

假设slow走一步,fast走三步,slow和fast一定会相遇吗?

结论:slow和fast不一定会相遇

fast会先进入环,slow后进入环,假设slow进环时,slow与fast之间的距离是N,slow进环以后,fast开始追击slow,slow每走一步,fast走三步,它们之间的距离缩小2,追击过程中,,它们之间距离的变化:

当N是偶数时

N

N-2

N-4

...

4

2

0

当它们之间的距离为0的时候,说明slow和fast相遇了

当N是奇数时

N

N-2

N-4

...

3

1

-1

当它们之间的距离为-1的时候,说明slow和fast错过了,进入下一轮追击,slow和fast的距离变成了C-1(C是环的长度),如果C-1是偶数则下一轮追上,否则永远追不上。

环形链表 II

给定一个链表的头节点  head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。如果 pos 是 -1,则在该链表中没有环。注意:pos 不作为参数进行传递,仅仅是为了标识链表的实际情况。

不允许修改 链表。

示例 1:

C语言中链表经典面试题目

输入:head = [3,2,0,-4], pos = 1
输出:返回索引为 1 的链表节点
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

C语言中链表经典面试题目

输入:head = [1,2], pos = 0
输出:返回索引为 0 的链表节点
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

C语言中链表经典面试题目

输入:head = [1], pos = -1
输出:返回 null
解释:链表中没有环。

提示:

  • 链表中节点的数目范围在范围 [0, 104] 内
  • -105 <= Node.val <= 105
  • pos 的值为 -1 或者链表中的一个有效索引

进阶:你是否可以使用 O(1) 空间解决此题?

解题思路:

方法一:

已知结论,一个指针从相遇点出发,另一个指针从链表表头开始走,它们一定会在入口相遇。

struct ListNode *detectCycle(struct ListNode *head) 
{
   struct ListNode* fast=head;
   struct ListNode* slow=head;
   while(fast&&fast->next)
   {
       fast=fast->next->next;
       slow=slow->next;
       if(fast==slow)//这里之前都是复用,判断链表是否带环的原码
       {
           struct ListNode* meet=slow;//相遇点的指针
           struct ListNode* cur=head;//链表表头指针
           while(meet!=cur)
           {
               cur=cur->next;
               meet=meet->next;
           }
           return meet;//入口点的位置
       }
   }  
   return NULL;  
}

结论的验证:

前提:slow走一步,fast走两步

推论:fast走的路程是slow的两倍

声明:链表表头到环入口点的距离:L,环入口点到相遇点点距离:X,环的长度:C

C语言中链表经典面试题目

slow走的路程:L+X(因为1圈之内,fast必定能够追上slow) 

fast走的路程:L+X+n*C(如果L很长,C很短,所以在slow进入环之前,fast可能走了不止一圈了,所以是n*C)

由推论可以的到:2*(L+X)=L+X+n*C   L=n*C-X

得到L=n*C-X,即证明了结论了

方法二:

在相遇的时候,将相遇的节点和下一个节点断开,如图所示:

C语言中链表经典面试题目

这样我们就可以,帮这个题看成,找两个链表相交的第一个节点。

struct ListNode *detectCycle(struct ListNode *head) 
{
    struct ListNode* slow=head;
    struct ListNode* fast=head;
    while(fast&&fast->next)
    {
        slow=slow->next;
        fast=fast->next->next;
        if(slow==fast)
        {
            struct ListNode* meet=fast;
            struct ListNode* meetNext=meet->next;
            meet->next=NULL;
            int LenHead=0,LenMeetNext=0;
            struct ListNode* n1=meetNext;
            struct ListNode* n2=head;
            while(n1)
            {
                n1=n1->next;
                LenHead++;
            }
            while(n2)
            {
                n2=n2->next;
                LenMeetNext++;
            }
            int gap=abs(LenHead-LenMeetNext);
            struct ListNode* longlist=meetNext;
            struct ListNode* shortlist=head;
            if(LenHead<LenMeetNext)
            {
                longlist=head;
                shortlist=meetNext;
            }
            while(gap--)
            {
                longlist=longlist->next;
            }
            while(longlist!=shortlist)
            {
                longlist=longlist->next;
                shortlist=shortlist->next;
            }
            return longlist;
        }
    }   
    return NULL;     
}

 

🌸🌸🌸如果大家还有不懂或者建议都可以发在评论区,我们共同探讨,共同学习,共同进步。谢谢大家! 🌸🌸🌸  文章来源地址https://www.toymoban.com/news/detail-434739.html

到了这里,关于C语言中链表经典面试题目的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Java中链表的实现(超详细)

            在Java中,链表可以通过 创建节点 和 链接节点 来实现。以下是一个简单的 链表实现 示例: 输出:         在这个示例中,我们创建了一个  LinkedList 类 ,它 包含一个 Node 类 和 一些方法 来操作链表。我们可以使用  push() 方法在链表的头部插入节点 ,使

    2024年02月14日
    浏览(12)
  • 61. 旋转链表 86. 分隔链表 |面试经典题

    题目 :给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。 题目链接 :61. 旋转链表 截断拼接即可 题目 :给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留

    2024年01月22日
    浏览(18)
  • 数据结构中链表的实现以及排序

    本期和大家主要分享的是关于数据结构中双向链表的实现过程,那么话不多说,来具体看看吧! 来分析一下,这里呢定义了一个int的数据类型,表明整个链表存放的是整形的数据;其次定义了链表节点的数据类型,其中包括了此节点存放的数据以及链接向下一个节点的地址;

    2024年02月02日
    浏览(14)
  • 链表经典面试题之二

     今天我们做一道环形链表的题目力扣141题https://leetcode.cn/problems/linked-list-cycle/  这道题让我们分析链表中是否存环,存在的话返回true,不存在返回false。首先看到这道题我们要捋顺思路,怎么才能达到它要的效果?要找出是否存在一个环,那么我们能不能看看尾结点的下一个

    2024年02月05日
    浏览(12)
  • 小白水平理解面试经典题目LeetCode 594 最大和谐字符串

    这道题属于字符串类型题目,解决的办法还是有很多的,暴力算法,二分法,双指针等等。 和谐数组是指一个数组里元素的最大值和最小值之间的差别 正好是 1 。 现在,给你一个整数数组 nums ,请你在所有可能的子序列中找到最长的和谐子序列的长度。 数组的子序列是一个

    2024年01月23日
    浏览(18)
  • 【C语言】经典题目(二)

    C站的小伙伴们,大家好呀^^! 这一篇文章是C语言之经典题目,快来跟我一起进入C语言的世界吧!💞 C语言其他刷题篇在这里哦: 【C】语言经典题目(一) 【C语言】字符串—刷题篇 给出三角形的边长,求三角形的面积。 利用海伦公式求三角形面积 area=根号下 s*(s-a)*(s-b

    2024年02月07日
    浏览(14)
  • 【pygame游戏开发】这几个经典游戏,小红书Python面试题目

    pygame.time.set_timer(change_hole_event, 800) mole = Mole(cfg.MOLE_IMAGEPATHS, hole_pos) hammer = Hammer(cfg.HAMMER_IMAGEPATHS, (500, 250)) clock = pygame.time.Clock() your_score = 0 flag = False init_time = pygame.time.get_ticks() while True: time_remain = round((61000 - (pygame.time.get_ticks() - init_time)) / 1000.) if time_remain == 40 and not flag: hole

    2024年04月25日
    浏览(11)
  • C语言天花板——指针(经典题目)

    指针我们已经学习的差不多了,今天我来给大家分享几个经典的题目,来让我们相互学习🏎️🏎️🏎️     ​       ​  图解: ​   ​     ​   ​       ​   ​    相信大家一定从今天的题目当中收获满满,希望大家有美好的一天!💓💓💓

    2024年01月17日
    浏览(24)
  • 经典C语言题目程序题(函数篇)

    经典的C语言函数篇题目,看完你期末考试就没有问题了!快来一起看看吧!!! 目录 1.编写一个函数,可以算出 任意两个整数的和,并返回相应的结果 2. 编写一个函数可以求出任意三个整数之中的最大值,并返回其最大值 3.编写一个函数,可以实现给出算数运算的功能,

    2024年02月01日
    浏览(13)
  • 小白水平理解面试经典题目LeetCode 404 Sum of Left Leaves【Tree】

    给定二叉树的root,返回所有左叶的总和。 叶子是没有子节点的节点。左叶是另一个节点的左子节点的叶。 在大学某个自习的下午,小白坐在教室看到这道题。想想自己曾经和白月光做题,现在大过年的,也是只有自己练题了。左边一颗树,右边一棵树。。。 这时候黑长直女

    2024年02月22日
    浏览(17)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包