• 22 链表中倒数第k个节点(第3章 高质量的代码-代码的鲁棒性)


    题目描述:

    输入一个链表,输出该链表中倒数第k个结点。

    尾节点是倒数第一个节点

    测试用例:  

    功能测试(第k个节点在中间、是头节点、是尾节点)

    特殊输入测试(链表头节点是nullptr指针、链表的头节点个数小于k、k=0)

    解题思路:

    1)使用两个指针,一个指针先移动k步,如果链表小于k,终止返回nullptr。然后两个指针同时移动,知道后一个指针移出最后一个节点    

    //实现1
    /* struct ListNode { int val; struct ListNode *next; ListNode(int x) : val(x), next(NULL) { } };*/ class Solution { public: ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { if(pListHead==nullptr || k=0)return nullptr; //不要忘记k<0的情况 无符号不用判断k<0时; ListNode* back = pListHead; //先将指针back移动到第k个元素的位置,索引k的位置 while(back!=nullptr && k>0){ //先判断k=0,然后才是k--。 back=back->next; k--; } if(k>0) //说明链表的长度<k return nullptr; ListNode* front = pListHead; while(back!=nullptr){ //back->next!=nullptr 是错误的。 back=back->next; front=front->next; } return front; } };  

     注:尾节点是倒数第一个节点,因此k=1时,front应该指向尾节点,此时back应该是刚好移出尾节点,为空nullptr。

    使用两个指针,一个指针先移动k-1步,如果链表小于k,终止返回nullptr。然后两个指针同时移动,知道后一个指针移动到最后一个节点

    //实现1
    /*
    struct ListNode {
    	int val;
    	struct ListNode *next;
    	ListNode(int x) :
    			val(x), next(NULL) {
    	}
    };*/
    class Solution {
    public:
        ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
            if(pListHead==nullptr || k==0)return nullptr;  //无符号,所以不用判断k<0;
            
            ListNode* back = pListHead;
            //先将指针back移动到第k-1个元素的位置,
            while(back->next!=nullptr && k-1>0){ //为了得知第k个元素是否存在,应该判断back->next!=nullptr而不是back!=nullptr
                back=back->next;
                k--;
            }
            if(k>1) //说明链表的长度<k
                return nullptr;
            
            ListNode* front = pListHead;
            while(back->next!=nullptr){ //back移动到最后一个元素即可
                back=back->next;
                front=front->next;
            }
            
            return front;
        }
    };
    
    //实现2
    class Solution {
    public:
        ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
            if(pListHead==nullptr || k==0)return nullptr;  //无符号,所以不用判断k<0;
            
            ListNode* back = pListHead;
            //先将指针back移动到第k-1个元素的位置,
            /*while(back->next!=nullptr && k-1>0){ //为了得知第k个元素是否存在,应该判断back->next!=nullptr而不是back!=nullptr
                back=back->next;
                k--;
            }
            if(k>1) //说明链表的长度<k
                return nullptr;*/
            for(unsigned int i=0;i<k-1;++i){
                if(back->next!=nullptr)
                    back=back->next;
                else
                    return nullptr;
            }
            
            ListNode* front = pListHead;
            while(back->next!=nullptr){ //back移动到最后一个元素即可
                back=back->next;
                front=front->next;
            }
            
            return front;
        }
    };
    

        

    对于unsigned int类型要格外注意,在写循环或者判断时,常会遇到对变量--;这种情况要格外注意:

    因为当unsigned int k=0; --k后,变量的值并不是-1,而是无符号的0xFFFFFFFF,如果此时判断k>0,还是会成立

    //该方法是错误的,当k=0是,K-1为0xFFFFFFFF,back会一直向后访问超出数组
    class Solution {
    public:
        ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
            if(pListHead==nullptr || k<0)return nullptr;
            
            ListNode* back = pListHead;
            //先将指针back移动到第k-1个元素的位置
           for(unsigned int i=0; i<k-1; ++i){
                bask=back->next;
            }
    
            if(k>1) //说明链表的长度<k
                return nullptr;
            
            ListNode* front = pListHead;
            //back移动到最后一个元素
            while(back->next!=nullptr){ //back->next!=nullptr
                back=back->next;
                front=front->next;
            }
            
            return front;
        }
    };
    

      

    相似题目:

    求链表的中间节点:如果链表中的节点总数为奇数,则返回中间节点;如果链表总数是偶数,则返回中间两个节点的任意一个。

    为了解决这个问题,也可以同时定义两个指针,同时从链表出发,一个指针一次走一步,另一个指针一次走两步。当走的快的指针走到链表末尾时,走的慢的指针正好在链表的中间。

  • 相关阅读:
    单调队列+二分 G
    dp cf 1700 最近几天的刷题
    dp 20190618
    dp 20190617
    dp cf 20190615
    dp cf 20190614
    powercli
    zabbix docker-weixin
    cenetos-大文件排序
    esxcli命令
  • 原文地址:https://www.cnblogs.com/GuoXinxin/p/10447460.html
Copyright © 2020-2023  润新知