zoukankan      html  css  js  c++  java
  • 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;
        }
    };
    

      

    相似题目:

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

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

  • 相关阅读:
    如何完全卸载oracle和删除oracle在注册表中的注册信息
    win10 管理工具中添加 oracle 10g驱动
    failed to install tomcat6 service ,check your setting and permissions
    ORA-28000: the account is locked-的解决办法
    Intellij Idea乱码解决方案
    过三关 Java冒泡排序选择排序插入排序小练习
    Java坦克大战(四)
    Java坦克大战(三)
    Java坦克大战(二)
    Java坦克大战(一)
  • 原文地址:https://www.cnblogs.com/GuoXinxin/p/10447460.html
Copyright © 2011-2022 走看看