剑指offer22:链表倒数第k个节点

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

链表长度未知,可以西安遍历一次得到链表长度,然后可计算出移动多少步. 然后这样做相当于遍历两次链表. 假如链表的倒数第K个节点存在,想要遍历一次就找到倒数第K个节点,设置两个指针指向头节点,让其中一个指针先走k-1步,然后两个指针一起向后移,当先走的指针走到链表尾时,另一个指针指向倒数第k个节点.

ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {
        if(pListHead==nullptr)
            return nullptr;
        if(k==0)
            return nullptr;
        ListNode* p1= pListHead;
        ListNode* p2= p1;
        for(int i=0;i<k-1;i++){
            if(p2->next!=nullptr){
                p2 = p2->next;
            }
            else{
                return nullptr;
            }
        }
        while(p2->next!=nullptr){
            p2 = p2->next;
            p1 = p1->next;
        }
        return p1;
    }

链表的中间节点:如果链表节点总数时奇数,返回中间节点,如果是偶数,返回中间两个的任意一个. 如果想要遍历一次,参考上诉思想,一个指针无法解决. 设置两个指针,两个指针同时出发,一个走一步,一个走两步,可以发现当走两步的指针走到表尾时,另一个指针刚好指向链表中间节点.

ListNode* FindMiddle(ListNode* pListHead){
    if(pListHead==nullptr)
        return nullptr;
    ListNode* p1=pListHead;
    ListNode* p2=p1;
    while(p2->next!=nullptr){
        p2 = p2->next;
        if(p2->next==nullptr)
            break;
        else:
            p1 = p1->next;
            p2 = p2->next;
    }
    return p1;
}

note:当对链表进行操作一个指针不能解决问题的时候,可以尝试用两个指针遍历链表,可以一快一慢,或让其中一个先走