何海涛算法面试题感悟之九:寻找链…

题目:输入一个单向链表,输出该链表中倒数第k 个结点。链表的倒数第0 个结点为链表的尾指针。链表结点定义如下:

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


这里,我们有两种思路,一种是遍历所有的单向链表,得到链表的长度n,然后第二次遍历该链表,找到正数第n-k+1个节点即可,这种思路的缺点是要两次遍历所有的节点,效率较低,对应的c++代码如下

ListNode* FindKthToTail_Solution1(ListNode* pListHead, unsigned int k)
{
      if(pListHead == NULL)
            return NULL;

      //首先统计出链表中节点的个数
      ListNode *pCur = pListHead;
      unsigned int nNum = 1;//默认已经有一个节点了
      while(pCur->m_pNext != NULL)
      {
            pCur = pCur->m_pNext;
            nNum ++;
      }

      // 如果节点个数小于K,那么直接返回NULL
      if(nNum < k)
            return NULL;

      //找到第n-k+1个节点,注意边界条件
      pCur = pListHead;
      for(unsigned int i = 1; i < nNum - k+1; ++ i)
            pCur = pCur->m_pNext;

       return pCur;
}

第一种思路需要两次的时间将链表中的节点读入物理内存,如果链表很长的话,显然很费时间

第二种思路是维持两个指针,他们之间的间隔为k-1,一个指针在前,一个指针在后,这样当前一个指针遍历到结尾的时候,后面的指针指向的便使第k个节点,首先,我们可以先让前面的指针走到第K个节点(从1开始),然后同时移动两个指针,直到前面的指针指向尾节点

ListNode* FindKthToTail_Solution1(ListNode* pListHead, unsigned int k){

  if(pListHead==NULL)

      return null;

 ListNode* first,*last;

 first = head = pListHead;

 for(int i=1;i< k;i++){//将前面的指针移到第K个位置,因为默认已经在第一个位置了,所以只需要移动k-1次

  if(first ->m_pNext!=NULL)first = first->m_pnext;

  else return NULL;

}

//运行到这里,两个指针的位置已经是相差k-1个了

while(first->m_pnext!=null){//同时移动两个指针

first = first->m_pNext;

last = last->m_pNext;

}

return last;

}


第二种算法的优越之处在于只需要将链表读入一次内存即可,巧妙地通过一些简单的数学计算和算法技巧来达到解决问题的目的。

本篇文档对应何海涛博客

http://zhedahht.blog.163.com/blog/static/2541117420072114478828/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值