您的位置:首页 > 职场人生

【剑指offer】面试题15、链表中倒数第 K 个结点

2015-06-19 21:05 429 查看
题目:输入一个链表,输出该链表中倒数第 k 个结点。本题从 1 开始计数,即链表的尾结点为倒数第一个结点。例如一个链表有 6 个结点,从头结点开始它们的值依次是 1、2、3、4、5、6。这个链表的倒数第 3 个结点是值为 4 的结点。


链表结点定义如下:

typedef struct Node
{
int m_nValue;
struct Node *m_pNext;
}ListNode, *pListNode;


方法一、遍历两次链表

第一次统计出链表中结点的个数;

第二次就能找到倒数第 k 个结点。

方法二、利用快慢指针

快慢指针:一个指针走在前面,另一个指针走在后面。(额,略显粗糙)


具体做法为:我们定义两个指针pFast、pSlow。

1、第一个指针pFast从链表的头指针开始遍历,并向前走 k-1,第二个pSlow指针保持不动;

2、从第 k 步开始, 第一个指针和第二个指针同时移动;

由于两个指针的距离始终保持为 k-1,当第一个指针 pFast 指针到达链表的尾结点时,第二个指针 pSlow 指针正好是倒数第 k 个结点。

注意:要考虑链表的长度是否少于 k 个。


测试代码如下:

 #include "stdio.h"
#include "stdlib.h"

#define N 10

// deleteNode.c
#include "stdio.h"
#include "stdlib.h"

#define N 10

typedef struct Node { int m_nValue; struct Node *m_pNext; }ListNode, *pListNode;

void createList(ListNode **pHead, int len)
{
ListNode *pTail = NULL;

while(len--)
{
ListNode *pNew = (ListNode*)malloc(sizeof(ListNode));
pNew->m_nValue = rand()%100;
pNew->m_pNext = NULL;

if(*pHead == NULL)
{
*pHead = pNew;
pTail = pNew;
}
else
{
pTail->m_pNext = pNew;
pTail = pNew;
}
}
}

void printList(ListNode *pHead)
{
while(pHead != NULL)
{
printf("%3d ", pHead->m_nValue);
pHead = pHead->m_pNext;
}
printf("\n");
}

ListNode *findKthToTail(ListNode *pHead, int k)
{
if(!pHead || k <= 0)
return NULL;

ListNode *pFast = pHead;
int i;
for(i = 1; i < k; ++i)
{
if(pFast->m_pNext != NULL)
pFast = pFast->m_pNext;
else
return NULL;
}
ListNode *pSlow = pHead;

while(pFast->m_pNext != NULL)
{
pFast = pFast->m_pNext;
pSlow = pSlow->m_pNext;
}
return pSlow;
}

int main(int argc, char const *argv[])
{
ListNode *pHead = NULL;

createList(&pHead, N);
printf("Before: ");
printList(pHead);

ListNode *kthNode = findKthToTail(pHead, 3);
printf("The Kth Node: %d\n", kthNode->m_nValue);

return 0;
}


View Code

本文完。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: