剑指offer(14)--链表中倒数第k个结点

本文介绍了如何找到链表中倒数第k个节点的三种方法:双指针移动、使用栈和递归。双指针法中,一个指针先移动k步,然后两个指针同时移动直到第一个指针到达链表末尾;栈法利用栈的特性实现;递归法则在递归过程中记录走过的节点,当达到k时返回该节点。
摘要由CSDN通过智能技术生成

倒转链表中第k个结点

在这里插入图片描述

法一:双指针移动

这题要求链表的倒数第k个节点,最简单的方式就是使用两个指针,第一个指针先移动k步,然后第二个指针再从头开始,这个时候这两个指针同时移动,当第一个指针到链表的末尾的时候,返回第二个指针即可。注意,如果第一个指针还没走k步的时候链表就为空了,我们直接返回null即可。

class Solution {
public:
    ListNode* FindKthToTail(ListNode* pHead, int k) {
        if(pHead==NULL) return NULL;
        ListNode* first=pHead;
        ListNode* second=pHead;
        while(k--){
            if(first==NULL) return NULL;
            first=first->next;
        }
        while(first != NULL){
            first=first->next;
            second=second->next;
        }
        return second;
    }
};

法二:用栈解决

class Solution {
public:
    ListNode* FindKthToTail(ListNode* pHead, int k) {
        if(pHead==NULL) return NULL;
        stack<ListNode*> v;
        int count=0;
        while(pHead!=NULL){
            v.push(pHead);
            pHead=pHead->next;
            count++;
        }
        ListNode* FirstNode=v.top();
        v.pop();
        ListNode* temp;
        if(count<k||k==0) return NULL;
        for(int i=1;i<k;i++){
            temp=v.top();
            temp->next=FirstNode;
            FirstNode=temp;
            v.pop();
        }
        return FirstNode;
    }
};

法三:递归返回

终止条件很明显就是当节点head为空的时候,就没法递归了,这里主要看的是逻辑处理部分,当递归往下传递到最底端的时候,就会触底反弹往回走,在往回走的过程中记录下走过的节点,当达到k的时候,说明到达的那个节点就是倒数第k个节点,直接返回即可,如果没有达到k,就返回空,搞懂了上面的过程,代码就很容易写了

class Solution {
    int cnt=0;//全局变量,记录递归往回走时访问的结点数量
public:
    ListNode* FindKthToTail(ListNode* pHead, int k) {
        //边界条件判断
        if(pHead==NULL) return NULL;
        ListNode* node=FindKthToTail(pHead->next,k);
        ++cnt;
        //从后往前数结点数小于k,返回空
        if(cnt<k){
            return NULL;
        }else if(cnt==k){
            //从后往前数结点数等于k,返回空当前传递进来的pHead
            return pHead;
        }else{//如果要返回倒数第0个结点,就需要这个条件来判断
            //注意此处不能省略cnt>k的情况,编译器会认为可能存在cnt>k的情况而出错
            //从后往前数结点数大于k,返回node
            return node;
        }
    }
};

上面代码在仔细一看,当size小于k的时候node节点就是空,所以我们可以把size大于k和小于k合并为一个,这样代码会更简洁一些

class Solution {
    int cnt=0;
public:
    ListNode* FindKthToTail(ListNode* pHead, int k) {
        if(pHead==NULL) return NULL;//即作为判断是否为空条件,也为递归跳出条件
        ListNode* node=FindKthToTail(pHead->next,k);
        if((++cnt) == k) return pHead;
        return node;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值