C++解OJ题--链表中倒数第K个结点(已在路上)

本文介绍了如何使用C++解决链表中倒数第K个节点的问题,提供了两种解决方案:一种是先遍历链表计算节点总数,另一种是使用快慢指针。快慢指针方案更为高效,只需遍历一次链表,适用于在线评测系统(OJ)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  世界这么大,人生这么长,总会有这么一个人,让你想要温柔对待。


原题如下:

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

审题:
  题目也还是很好理解,就是输出一个单链表的倒数第K个结点。

可能给我们的单链表的情况:
1.空的单链表;
2.有多个结点,但是K的值不合理(即K的值大于链表的长度或K小于1);
3.有多个结点,且K的值是合理的。


方案设计:
   本题的核心问题是如何确定K的值
第一种方案:
  这种方案肯定是大家都能想到的,就是先通过遍历一遍链表,计算出单链表有几个结点。则可以判断K值是否合理,也就可以得出其倒数第K个结点是哪一个结点了。这种方案易懂,编写算法也容易,但是这种方案相比执行效率不高,毕竟要通过遍历两次。在这里就不分析过程了,直接给出代码如下:

class Solution {
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
        if(k<1||head==NULL)return NULL;
        int num=0;
        ListNode*traversal=head;
        while(traversal)//计算链表有几个结点
        {
            num++;
            traversal=traversal->next;
        }
        traversal=head;//重新指向头结点
        if(k>num)return NULL;//判读K值是否合理
        for(int i=0;i<num-k;i++)
        {
            traversal=traversal->next;
        }
        return traversal;
    }
};

第二种方案:
   第二种方案,根据其给的K值出发,利用快慢双指针让快指针先走K个结点。如果快指针还没有走完这K次就指向了NULL,则认为K是不合理的。否则再让两个指针一起走,当快指针为NULL时,慢指针所指的结点就是倒数第K个结点。假如有如下的单链表:k=2
在这里插入图片描述
   让快指针和慢指针都初始为指向第一个结点,如下:
在这里插入图片描述
   让快指针先走K个结点,即两个结点,如下:
在这里插入图片描述
  再让快慢指针一起走,当快指针指向NULL时,慢指针所指的结点就是倒数第K个结点,如下:
在这里插入图片描述

  这种方案的基本原理在于两个指针始终保持K个结点的距离。

代码实现如下:

class Solution {
public:
    ListNode* getKthFromEnd(ListNode* head, int k) {
        if(k<1||head==NULL)return NULL;
        ListNode*fast=head;
        ListNode*slow=head;
        for(int i=0;i<k;i++)//让快指针提前走K个结点
        {
            fast=fast->next;
        }
        while(fast)//再让快慢指针一起走
        {
            fast=fast->next;
            slow=slow->next;
        }
        return slow;
    }
};

  这种方案只需要遍历一次单链表就可以了。


  学会了嘛,我是老胡,感谢阅读!!❤️ ❤️

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值