寻找链表中倒数第k个结点

来源:互联网 发布:西安java程序员招聘 编辑:程序博客网 时间:2024/05/21 10:08
//1.相当于遍历链表两次,第一次结点指针全部入栈,第二次找到倒数第k个结点ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) {//注意防御性编程: //1.如果k大于链表的个数.//2.如果k为0//3.如果链表为空if ( NULL == pListHead || 0 == k )return NULL;stack<ListNode*> s;while ( NULL != pListHead ){s.push( pListHead );pListHead = pListHead->next;}if ( s.size( ) < k )return NULL;        for ( size_t i = 1; i < k; ++i )            s.pop( );return s.top( );}//2.只需遍历链表一次的解法://大致思路: 两个指针都指向头节点,第一个指针先在链表上走k-1步,此时第二个指针和第一个指针同时向后走,当第一个指针走到结尾时,第二个指针的指向就是倒数第k个结点。ListNode* FindKthToTail(ListNode* pListHead, unsigned int k){if ( NULL == pListHead || 0 == k )return NULL;size_t count = 0;ListNode* pNode1 = pListHead;ListNode* pNode2 = pListHead;//根据我们思路以及前面判断过的k不等于0. 所以k-1至少为0.for ( size_t i = 0; i < k-1; ++i, ++count ){if ( NULL == pNode1 )return NULL;pNode1 = pNode1->next;}//注意,如果k给的有问题,如大于链表元素个数//程序到这时pNode1已有可能为NULLif ( NULL == pNode1 )return NULL;while ( NULL != pNode1->next ){++count;pNode1 = pNode1->next;pNode2 = pNode2->next;}if ( count+1 < k/*count + 1 为链表中结点个数*/ )return NULL;elsereturn pNode2;}//注意,我们写完这种思路后再来分析,和第一种思路相比,第二种思路确实只遍历了链表一次。//可是第二种思路边界情况太多,需要注意可能会出错地方太多,相比之下,第一种思路通俗易懂也不易出错。//注意有unsigned int 类型变量时一定要小心注意 这种变量值为0 时减去一个正数。//下面是 剑指offer上代码,比上述代码简洁,也少去了不必要的判断.ListNode* FindKthToTail(ListNode* pListHead, unsigned int k){if ( NULL == pListHead || 0 == k )return NULL;ListNode* pAhead = pListHead;ListNode* pBehind = NULL;for ( size_t i = 0; i < k-1; ++i ){if ( NULL != pAhead->next )pAhead = pAhead->next;elsereturn NULL;}pBehind = pListHead;while ( NULL != pAhead->next ){pAhead = pAhead->next;pBehind = pBehind->next;}return pBehind;}