剑指Offer面试题:12.链表的倒数第K个结点

一 题目:链表的倒数第K个结点

题目:输入一个链表,输出该链表中倒数第k个结点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾结点是倒数第1个结点。例如一个链表有6个结点,从头结点开始它们的值依次是1、2、3、4、5、6。这个链表的倒数第3个结点是值为4的结点。

二 解题思路

  抛开常规解法,采用只遍历一次就能找到倒数第k个结点,可以定义两个指针:

  (1)第一个指针从链表的头指针开始遍历向前走k-1,第二个指针保持不动

  (2)从第k步开始,第二个指针也开始从链表的头指针开始遍历

  (3)由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个结点

三 代码实现

template <typename T>
struct Node
{
public:
    T data;
    Node *pNext;
};

template <typename T>
class ListEx
{
private:
    Node<T> *m_pHead;
    Node<T> *m_pTail;
public:
    ListEx()
    {
        m_pTail = m_pHead = NULL;
    }
    ~ListEx()
    {
        Node<T> *pTemp = NULL;
        Node<T> *pNode = m_pHead;
        while (pNode)
        {
            pTemp = pNode;
            pNode = pNode->pNext;
            delete pTemp;
        }

        m_pHead = m_pTail = NULL;
    }
    void add(T data)
    {
        Node<T> *pNode = new Node<T>;
        pNode->data = data;
        pNode->pNext = NULL;

        if (m_pHead == NULL)
        {
            m_pTail = m_pHead = pNode;
        }

        Node<T>* pTemp = m_pTail;
        pTemp->pNext = pNode;
        m_pTail = pNode;
    }

    Node<T> *GetListHead()
    {
        return m_pHead;
    }
};

// 链表的倒数第k个结点,注意倒数从1开始
template <typename T>
Node<T>* FindKthToTail(Node<T> *pNode, int k)
{
    // k必须不大于Node的结点数目
    if (!pNode || k < 0) return NULL;
    Node<T> *p1 = pNode;
    Node<T> *p2 = pNode;

    int nIndex = 0;
    bool bStart = false;
    int nFalg = 0;
    while (NULL != p2->pNext)
    {
        if (nIndex == k-1)
        {
            bStart = true;
        }
        if (bStart)
        {
            p1 = p1->pNext;
        }

        p2 = p2->pNext;
        nIndex ++;
    }
    return p1;
}

void main()
{
    ListEx<int> *pList= new ListEx<int>();
    pList->add(1);
    pList->add(2);
    pList->add(3);
    pList->add(4);
    pList->add(5);
    pList->add(6);
    pList->add(7);

    Node<int> *pHead = pList->GetListHead();
    Node<int> *pNode = FindKthToTail(pHead, 2);
    cout << pNode->data <<endl;
    pNode = FindKthToTail(pHead, 1);
    cout << pNode->data <<endl;
    pNode = FindKthToTail(pHead, 7);
    cout << pNode->data <<endl;

    delete pList;
}

 

posted @ 2018-04-17 16:06  Fate0729  阅读(170)  评论(0编辑  收藏  举报