首页 > 试题广场 >

链表中倒数最后k个结点

[编程题]链表中倒数最后k个结点
  • 热度指数:358587 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 256M,其他语言512M
  • 算法知识视频讲解
输入一个长度为 n 的链表,设链表中的元素的值为 ai ,返回该链表中倒数第k个节点。
如果该链表长度小于k,请返回一个长度为 0 的链表。


数据范围:
要求:空间复杂度 ,时间复杂度
进阶:空间复杂度 ,时间复杂度

例如输入{1,2,3,4,5},2时,对应的链表结构如下图所示:
其中蓝色部分为该链表的最后2个结点,所以返回倒数第2个结点(也即结点值为4的结点)即可,系统会打印后面所有的节点来比较。
示例1

输入

{1,2,3,4,5},2

输出

{4,5}

说明

返回倒数第2个节点4,系统会打印后面所有的节点来比较。 
示例2

输入

{2},8

输出

{}

说明:本题目包含复杂数据结构ListNode,点此查看相关信息
typedef struct ListNode ListNode;
struct ListNode* FindKthToTail(struct ListNode* pHead, int k )
{   
    //合法性判断
    if(pHead == NULL || k == 0)
    {
        return NULL;
    }

    int i = 0;
    ListNode* fast = pHead;
    ListNode* slow = pHead;

    //快指针先走k步
    for(i = 0; i < k; i++)
    {
        //判断链表是否足够长
        if(fast == NULL && i != k - 2)
        {
            return NULL;
        }
        fast = fast->next;
    }

    //快慢指针同时前行,它们之间的距离恒为k
    while(fast != NULL)
    {
        fast = fast->next;
        slow = slow->next;
    }

    return slow;
}

发表于 2024-03-31 11:20:06 回复(0)
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    struct ListNode* p1=pHead;
    int ListNum=0, i=0;
    while(p1 != NULL) {
        p1 = p1->next;
        ListNum++;
    }
    if(k>ListNum)
        return NULL;
    p1=pHead;
    while(i<ListNum-k) {
        p1 = p1->next;
        i++;
    }
    return p1;
}

发表于 2024-03-15 13:53:48 回复(0)

struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    struct ListNode* head=pHead;
    int len=0;
    while(head)
    {
        head = head->next;
        len++;
    }
    len=len-k;
    if(len<0)
    {
        return NULL;
    }
    while(len)
    {
        pHead=pHead->next;
        len--;
    }
    return pHead;
}
编辑于 2024-03-02 20:41:44 回复(1)
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    struct ListNode* fast=pHead;
    struct ListNode* slow=pHead;
    for(int i=0;i<k;i++)
    {
        if(fast==NULL)
        {
            return NULL;
        }
        fast=fast->next;
    }
    while(fast)
    {
        fast=fast->next;
        slow=slow->next;
    }
    return slow;
}
发表于 2023-09-06 15:53:09 回复(0)
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    // write code here
    struct ListNode * p = pHead;
    int count=0;

    while (p) {
        p = p->next;
        count++;
    }
    p = pHead;
   
    if(count < k)
        return NULL;
    if(count == k)
        return p;
    count = count - k - 1;
    while (count--) {
        p = p->next;
    }
    return p->next;
}
发表于 2023-09-04 16:16:43 回复(0)
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    //快慢指针
    struct ListNode* fast = pHead; 
    struct ListNode* slow = pHead;
    int i=0;

    for (i=0; i<k; ++i) //快指针先走k步
    {
        if(fast==NULL) return NULL; //链表长度小于k,返回空指针
        fast = fast->next;
    }

    while (fast!=NULL) //快指针到链表末尾,慢指针到想要的节点位置
    {
        fast = fast->next;
        slow = slow->next;
    }

    return slow;
}

发表于 2023-08-19 20:01:39 回复(0)
/**
 * struct ListNode {
 *	int val;
 *	struct ListNode *next;
 * };
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param pHead ListNode类 
 * @param k int整型 
 * @return ListNode类
 */
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    // write code here
    int iNum = 0;
    struct ListNode* ptr = pHead;

    while (ptr) {
        iNum++; ptr = ptr->next;
    }

    if (iNum < k) {
        return  NULL;
    }else{
        ptr = pHead;
        int i = iNum - k;
        while (i--) {
            ptr = ptr->next;
        }
        return  ptr;
    }
}

发表于 2023-01-16 17:43:46 回复(0)
/**
 * struct ListNode {
 *  int val;
 *  struct ListNode *next;
 * };
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param pHead ListNode类 
 * @param k int整型 
 * @return ListNode类
 */
struct ListNode* FindKthToTail(struct ListNode* pHeadint k ) {
    // write code here

    if(pHead == NULL || k == 0)
        return NULL;
    struct ListNode *p = pHead;
    struct ListNode *pre = pHead;
    for(int i = 0; i < k-1; i++)
    {
        p = p->next;
        if(p == NULL)
            return NULL;
    }
    while(p->next != NULL)
    {
        p = p->next;
        pre = pre->next;
    }

    return pre;
}
发表于 2022-11-12 21:03:28 回复(0)
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) 
{
    if(!pHead)
    {
        return NULL;
    }
    struct ListNode *p = pHead;
    struct ListNode *q = pHead;
    while(k--)
    {
        q = q->next;
        if(!q && k)
        {
            p = NULL;
            break;
        }
    }
    while(q)
    {
        p = p->next;
        q = q->next;
    }
    return p;
    // write code here
}

发表于 2022-11-02 21:17:30 回复(0)
双指针法进阶解法
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    // write code here
    if(pHead==NULL||k==0) return 0;   //空链表和倒数第0个节点都返回0
    struct ListNode *p=pHead,*q=pHead;   //双指针法,定义两个链表类型的指针,达到进阶的空间复杂度O(1)  
    for(int i=1;i<k;i++){                 //for循环让p和q的距离保持为k
        q=q->next;
        if(q==NULL) return 0;            //如果链表长度不够k,则返回0
    }
    while(q->next!=NULL){             //p和q同步往后走,让q指向最后一个节点,p则为倒数第k个节点
        p=p->next;
        q=q->next;
    }
    return p;                      //返回p即可
}

发表于 2022-10-07 14:51:03 回复(0)
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    int len = 0, pos, i;
    struct ListNode* c = pHead;
    while(c) {
        len++;
        c = c->next;
    }
    if(k > len) return NULL;
    else {
        pos = len - k;
        c = pHead;
    }
    for(i = 0; i< pos; i++) {
        c = c->next;
    }
    return c;
}

发表于 2022-09-16 15:02:14 回复(0)
递归求解:
int temp=0;
struct ListNode* Recursion(struct ListNode* head,int k);

struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    // write code here
    if(k==0){
        return 0;
    }
    struct ListNode* hp=(struct ListNode*)malloc(sizeof(struct ListNode));
    hp->next=pHead;
    struct ListNode* np=Recursion(hp,k);
    if(temp<k){
        return 0;
    }else{
        return np;
    }
}
struct ListNode* Recursion(struct ListNode* head,int k){
    if(head->next==0){
        return head;
    }
    struct ListNode* p0=Recursion(head->next,k);
    temp=temp+1;
    if(temp>=k){
        return p0;
    }
    return head;
}


发表于 2022-08-18 21:54:11 回复(0)
/**
 * struct ListNode {
 *    int val;
 *    struct ListNode *next;
 * };
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 *
 * C语言声明定义全局变量请加上static,防止重复定义
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param pHead ListNode类 
 * @param k int整型 
 * @return ListNode类
 */
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    // write code here
    struct ListNode *p=pHead;
    struct ListNode *q=pHead;
    int count=0;
    while(p!=NULL){
        p=p->next;
        count++;
    }
    if(count-k<0){
        return NULL;
    }
    else if(count-k==0){
        return q;
    }
    else{
        for(int i=0; i<count-k; i++){
            q=q->next;
        }
        return q;
        }
    
}
发表于 2022-06-23 11:32:41 回复(0)
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    // write code here
    struct ListNode*p0;
    p0=pHead;
    int n=0;
    while(p0!=NULL){
        p0=p0->next;//指向结点的最后一个,直到为空
        n++;//计算结点总数
    }
    if(n<k){//返回的结点必须小于总结点数
        return NULL;
    }
    p0=pHead;//p0重新指向结点头
    for(int i=0;i<(n-k);i++)//结点总数(5)-返回第几个结点(2)=从第(3)个结点开始
    {
        p0=p0->next;
    }
    return p0;
}

发表于 2022-04-23 08:52:07 回复(0)
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) 
{
    // write code here
    struct ListNode* tail=pHead;
    int count=0;
    while(tail)
    {
        tail=tail->next;
        count++;
    }
    struct ListNode* start=pHead;
    if(k>count)
    {
        return NULL;
    }
    for(int i=0;i<count-k;i++)
    {
        start=start->next;
    }
    return start;
}

发表于 2022-04-13 21:55:25 回复(0)
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) 
{
    if(pHead==NULL)
    {
        return pHead;
    }
    struct ListNode *p1=pHead,*p2=pHead;
    for(int i=0;i<k;i++)
    {
        if(p2==NULL)
        {
            return p2;
        }
        p2=p2->next;
    }
    while(p2!=NULL)
    {
        p1=p1->next;
        p2=p2->next;
    }
    return p1;
}
//还有一种思路是求链表长度,再用链表长度减去K,写出一个for循环,可以找到倒数第K个节点,但是被空间复杂度限制。。。
发表于 2022-04-09 11:51:00 回复(0)
/**
 * struct ListNode {
 *    int val;
 *    struct ListNode *next;
 * };
 */
/**
 * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
 *
 * 
 * @param pHead ListNode类 
 * @param k int整型 
 * @return ListNode类
 */
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    if(pHead==NULL||k==0)
        return NULL;
    struct ListNode  *pa=pHead;
    struct ListNode  *pb=pHead;
    for(int i=0;i<k-1;i++){
        if(pa->next!=NULL){
            pa=pa->next;
        }
        else{
            return NULL;
        }
    }
    while(pa->next!=NULL){
        pa=pa->next;
        pb=pb->next;
    }
    return pb;
    // write code here
}
这个是排行上的代码,用时2ms,内存376KB,在我的电脑上28ms,内存5164KB?其他的题目我的电脑确实也都比别人慢,但是不可能差这么多,一般是人家3ms,我6ms这样!
这是为啥?
发表于 2022-04-07 15:41:57 回复(1)
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    if(pHead == NULL) return pHead;
    struct ListNode *p = pHead,*pn = pHead;
    for(int i = 0;i<k;i++){
        if(pn == NULL) return pn;
        pn = pn->next;
    }
    while(pn){
        p = p->next;
        pn = pn->next;
    }
    return p;
    // write code here
}

发表于 2022-03-16 13:34:03 回复(0)
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    //快慢指针干一波,这次不是1、2,1、2的走,而是快先走,然后快慢一起走
    struct ListNode* slow = pHead, * fast = pHead;
    
    while(fast && k)//快指针先走k步
        {
            fast = fast->next;
            k--;
        }
    if(!fast && k)//如果fast已经空,k不等0,那么k长度大于链表,返回null
        return NULL;
    
    while(fast)//快慢指针一起走,当快指针走向空,slow当前就是k的位置
    {
        slow = slow->next;
        fast = fast->next;
    }
    return slow;//假设k=0,到这一步,slow也是指向空
}

发表于 2021-11-08 00:52:42 回复(0)
struct ListNode* FindKthToTail(struct ListNode* pHead, int k ) {
    // write code here
    struct ListNode *cur = pHead;
    struct ListNode *pre = pHead;
    int loop = 0;
    for (loop = 0; cur && loop < k; loop++) {
        cur = cur->next;
    }
    if (loop < k) {
        return NULL;
    }
    while (cur) {
        cur = cur->next;
        pre = pre->next;
    }
    return pre;
}

发表于 2021-09-19 10:23:02 回复(0)

问题信息

上传者:灵溪吴彦祖
难度:
21条回答 5804浏览

热门推荐

通过挑战的用户

查看代码