No. 10 - K-th Node from End

No. 10 - K-th Node from End


Problem: Get the K th node from end of a linked list. It counts from 1 here, so the 1 st node from end is the tail of list. 

For instance, given a linked list with 6 nodes, whose value are 1, 2, 3, 4, 5, 6, its 3 rd node from end is the node with value 4.

A node in the list is defined as:

struct ListNode
{
     int       m_nValue;
    ListNode* m_pNext;
};

Analysis: In a list with n nodes, its k th node from end should be the (n-k+1) th node from its head. Therefore, if we know the number of nodes n in a list, we can get the required node with n-k+1 steps from its head. How to get the number n? It is easy if we scan the whole list from beginning to end.

The solution above needs to scan a list twice: We get the total number of nodes with the first scan, and reach the k th node from end with the second scan. Unfortunately, interviewers usually expect a solution which only scans a list once.

We have a better solution to get the k th node from end with two pointers. Firstly we move a pointer (denoted as P1) k-1 steps beginning from the head of a list. And then we move another pointer (denoted as P2) beginning from the head, and continue moving the P1 forward at same speed. Since the distance of these two pointers is always k-1, P2 reaches the k th node from end when P1 reaches the tail of a list. It scans a list only once, and it is more efficient than the previous solution.


It simulates the process to get the 3 rd node from end of a list with 6 nodes in Figure 1. We firstly move P1 2 steps (2=3-1) to reach the 3 rd node (Figure 1-a). Then P2 points to the head of a list (Figure 1-b). We move two pointers at the same speed, when the P1 reaches the tail, what P2 points is the 3 rd node from end (Figure 1-c).

The sample code of the solutions with two pointers is shown below:

ListNode* FindKthToTail(ListNode* pListHead,  unsigned  int k)
{
     if(pListHead == NULL || k == 0)
         return NULL;

    ListNode *pAhead = pListHead;
    ListNode *pBehind = NULL;

     for( unsigned  int i = 0; i < k - 1; ++ i)
    {
         if(pAhead->m_pNext != NULL)
            pAhead = pAhead->m_pNext;
         else
        {
             return NULL;
        }
    }

    pBehind = pListHead;
     while(pAhead->m_pNext != NULL)
    {
        pAhead = pAhead->m_pNext;
        pBehind = pBehind->m_pNext;
    }

     return pBehind;
}

The author Harry He owns all the rights of this post. If you are going to use part of or the whole of this ariticle in your blog or webpages,  please add a reference to  http://codercareer.blogspot.com/. If you are going to use it in your books, please contact me (zhedahht@gmail.com) . Thanks.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值