【C语言刷题】链表中快慢指针的应用

活动地址:CSDN21天学习挑战赛

链表中快慢指针的应用

Leetcode876——链表的中间结点

题目描述

给定一个头结点为 head 的非空单链表,返回链表的中间结点。
如果有两个中间结点,则返回第二个中间结点。

链接:Leetcode876

示例

示例 1:
输入:[1,2,3,4,5] **输出:**此列表中的结点 3

示例 2:
输入:[1,2,3,4,5,6] **输出:**此列表中的结点 4

提示:

  • 给定链表的结点数介于 1 和 100 之间。

核心代码模式

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* middleNode(struct ListNode* head)
{
    
}

思路分析和代码实现(C语言)

1.用链表长度除2法

这个方法很简单,先遍历一遍链表,用计数器把链表长度记下来,把长度除以2就是要移动的步数,然后再遍历链表找中间结点。

代码实现

struct ListNode* middleNode(struct ListNode* head)
{
    int cnt = 0;
    struct ListNode* cur = head;
    struct ListNode* mid = head;
    while(cur)
    {
        cnt++;
        cur = cur->next;
    }
    cnt /= 2;
    while(cnt--)
    {
        mid = mid->next;
    }
    return mid;
}

2.快慢指针(二倍速)

顾名思义,就是两个指针一个先在前面走,另一个后在后面走,不是要找中间结点吗,那让快指针一次走两步,慢指针一次走一步,那快指针移动步数就是慢指针的两倍咯,那好,当快指针走到链表尾部的时候是不是慢指针就走到中间位置了呢,不过要根据链表长度是奇数还是偶数来确定尾部的处理方式。这个方法比上面那个方法好一点点,就是少一次遍历。
image.png
代码实现

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

Leetcode JZ22——链表中倒数第k个结点

题目描述

输入一个链表,输出该链表中倒数第k个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。
例如,一个链表有 6 个节点,从头节点开始,它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个节点是值为 4 的节点。

链接Leetcode 🗡☞offer22

示例:
给定一个链表: 1->2->3->4->5, 和 _k _= 2. 返回链表 4**->5**.

核心代码模式

/**
 * Definition for singly-linked list.
 * struct ListNode {
 *     int val;
 *     struct ListNode *next;
 * };
 */


struct ListNode* getKthFromEnd(struct ListNode* head, int k){

}

思路分析与代码实现(C语言)

有一个思路是遍历用计数器求出链表长度,然后用它减去k就得到了要移动的步数,再让一个指针移动到对应位置即可。

我们这里考虑用快慢指针,可能有人会问了,这要怎么用呀?快慢指针不一定就是走得快或走得慢,可以是快指针先出发,慢指针后出发。在这里,先让快指针移动k步,这样的话一开始快指针就和慢指针的距离就是k-1,这时候再让快慢指针一同移动,直到快指针指向NULL,这时从链表尾部算起慢指针指向位置就是倒数第k位了。

不过链表相关的题目一定要注意一些细节,特别是可能的空指针和野指针的问题要考虑,那在这里有没有潜在的问题呢?有,如果链表为空,那么fast一开始就是NULL,如果直接让fast向后移动k步的话,会出现fast = fast->next语句,就会解引用NULL指针了,就会出问题,这是我们要考虑提防的点,所以要先加上一个判断if(fast == NULL),如果为空就直接返回NULL。
image.png

struct ListNode* getKthFromEnd(struct ListNode* head, int k)
{
    struct ListNode* fast = head;
    struct ListNode* slow = head;

    while(k--)
    {
        if(fast == NULL)
            return NULL;
        fast = fast->next;
    }
    
    while(fast)
    {
        fast = fast->next;
        slow = slow->next;
    }

    return slow;
}

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

桦秋静

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值