剑指offer 面试题22 链表中倒数第k个节点

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

思路一:最简单的思路是:先遍历一次链表,得出共n个节点,倒数第k个,既是正数第n-k+1个节点,直接遍历到第n-k+1个节点即可,但是需要遍历两次链表,如果需要遍历一次链表的方法时用思路二。

思路二:定义两个指针,第一个指针先指向第k个节点,既向前走k-1步,然后另第二个指针指向头结点,然后两个指针一起向后移动,直到第一个指针走到最后一个节点时,此时第二个指针正好指向倒数第k个节点。

但需注意:1.要判断输入是否为空指针,若为空指针,代码试图访问空指针会造成程序崩溃,所以此时要返回NULL。

                  2.若k大于链表的节点数,此时也会试图访问空指针,也要返回NULL。

               3.k==0时,k-1是无符号数,不是-1,也会造成崩溃。


class Solution {
public:
    ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) 
    {
        if (pListHead==NULL||k==0)
            return NULL;
        ListNode* p1= pListHead;
        ListNode* p2= NULL;
        for(unsigned int i=0;i<k-1;i++) 
        {
            if( p1->next!= NULL) //
            {
                p1=p1->next;
                
            }
            else
            {
               return NULL; 
            }
        }
       p2=pListHead;
        while (p1->next!=NULL)    //
        {
            p1=p1->next;
            p2=p2->next;
        }
    return p2;
    }
};

 补充题型:删除链表的倒数第N个节点

思路:同上题,找到倒数第k个节点,讲k的前一节点指向k的后一节点,既实现了删除节点的功能。

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) 
    {
        if(head==NULL||n==0)
            return NULL;
        ListNode* p1=head;  
        ListNode* p2=head;
        ListNode* p3=NULL;
        for(int i=0;i<=n-1;i++)
        {
            if(p1!=NULL)
                p1=p1->next;
            else
            {
             return NULL;   
            }
        }
        while(p1!=NULL)
        {
            p1=p1->next;
            p3=p2;    //保存要删除节点的前一节点
            p2=p2->next;
        }
        if(p2==head)     //如果要删除节点为头结点
           {head=head->next;}
        else
        {p3->next=p2->next;}
        
        return head;
        
    }
};


猜你喜欢

转载自blog.csdn.net/qq_42209189/article/details/80353836