面试100题:13.求单向链表倒数第k个节点

来源:互联网 发布:大数据 税收风险管理 编辑:程序博客网 时间:2024/05/14 14:55

题目

输入一个单向链表,输出该链表中倒数第k个结点,链表的倒数第0个结点为链表的尾指针。

分析

因为是单向链表,不能从尾部向头部遍历,所以要找到一种合适的方法遍历到倒数第K个节点。

解一

假设整个链表有n个结点,那么倒数第k个结点是从头结点开始的第n-k-1个结点(从0开始计数)。如果我们能够得到链表中结点的个数n,那我们只要从头结点开始往后走n-k-1步就可以了。如何得到结点数n?这个不难,只需要从头开始遍历链表,每经过一个结点,计数器加一就行了。这种思路的时间复杂度是O(n),但需要遍历链表两次。第一次得到链表中结点个数n,第二次得到从头结点开始的第n-k-1个结点即倒数第k个结点。

  1. /*Title:    13.求单向链表倒数第k个节点:解一 
  2. Author:     gocode 
  3. Date:       2012-10-15*/  
  4.   
  5. #include <iostream>  
  6. using namespace std;  
  7.   
  8. struct ListNode  
  9. {  
  10.     int m_nKey;  
  11.     ListNode* m_pNext;  
  12. };  
  13.   
  14. ListNode* Head;  
  15. ListNode* pCur;  
  16.   
  17. void AddToList(ListNode* &pCur, unsigned int key)  
  18. {  
  19.     if(pCur == NULL)  
  20.     {  
  21.         ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));  
  22.         newNode->m_nKey = key;  
  23.         newNode->m_pNext = NULL;  
  24.         pCur = newNode;  
  25.         Head = newNode;  
  26.     }  
  27.     else  
  28.     {  
  29.         ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));  
  30.         newNode->m_nKey = key;  
  31.         newNode->m_pNext = NULL;  
  32.         pCur->m_pNext = newNode;  
  33.         pCur = newNode;  
  34.     }  
  35. }  
  36.   
  37. ListNode* FindKthToTail_Solution1(ListNode* pListHead, unsigned int k)  
  38. {  
  39.     if(pListHead == NULL)  
  40.         return NULL;  
  41.   
  42.     // 计算链表里节点个数  
  43.     ListNode *pCur = pListHead;  
  44.     unsigned int nNum = 0;  
  45.     while(pCur != NULL)  
  46.     {  
  47.         pCur = pCur->m_pNext;  
  48.         nNum ++;  
  49.     }  
  50.     // 如果链表节点数小于k,则退出  
  51.     if(nNum < k)  
  52.         return NULL;  
  53.   
  54.     // 倒数第k个节点也是整数第n-k个节点  
  55.     // 找到它  
  56.     pCur = pListHead;  
  57.     for(unsigned int i = 0; i < nNum - k; ++ i)  
  58.         pCur = pCur->m_pNext;  
  59.     return pCur;  
  60. }  
  61.   
  62. void DisplayList(ListNode* pHead)  
  63. {  
  64.     ListNode* p = pHead;  
  65.     if(p == NULL)  
  66.         cout<<"The LinkedList is empty."<<endl;  
  67.     else  
  68.     {  
  69.         while(p != NULL)  
  70.         {  
  71.             cout<<p->m_nKey<<" ";  
  72.             p = p->m_pNext;  
  73.         }  
  74.     }  
  75.     cout<<endl;  
  76. }  
  77.   
  78. void main()  
  79. {  
  80.     Head = pCur = NULL;  
  81.   
  82.     AddToList(pCur, 1);  
  83.     AddToList(pCur, 2);  
  84.     AddToList(pCur, 3);  
  85.     AddToList(pCur, 4);  
  86.     AddToList(pCur, 5);  
  87.     AddToList(pCur, 6);  
  88.     AddToList(pCur, 7);  
  89.   
  90.     DisplayList(Head);  
  91.   
  92.     cout<<"13.求单向链表倒数第k个节点:解一"<<endl;  
  93.     cout<<"The Kth from tail is: "<<FindKthToTail_Solution1(Head, 3)->m_nKey<<endl;  
  94.     system("pause");  
  95. }  

解二

设置p1p2两个指针,开始时均指向头指针head,然后p2向后移动k个节点,接着同时移动p1p2节点,当p2指向尾部NULL时,此时p1指向的就是倒数第k个节点。

  1. /*Title:    13.求单向链表倒数第k个节点:解二 
  2. Author:     gocode 
  3. Date:       2012-10-15*/  
  4.   
  5. #include <iostream>  
  6. using namespace std;  
  7.   
  8. struct ListNode  
  9. {  
  10.     int m_nKey;  
  11.     ListNode* m_pNext;  
  12. };  
  13.   
  14. ListNode* Head;  
  15. ListNode* pCur;  
  16.   
  17. void AddToList(ListNode* &pCur, unsigned int key)  
  18. {  
  19.     if(pCur == NULL)  
  20.     {  
  21.         ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));  
  22.         newNode->m_nKey = key;  
  23.         newNode->m_pNext = NULL;  
  24.         pCur = newNode;  
  25.         Head = newNode;  
  26.     }  
  27.     else  
  28.     {  
  29.         ListNode* newNode = (ListNode*)malloc(sizeof(ListNode));  
  30.         newNode->m_nKey = key;  
  31.         newNode->m_pNext = NULL;  
  32.         pCur->m_pNext = newNode;  
  33.         pCur = newNode;  
  34.     }  
  35. }  
  36.   
  37. ListNode* FindKthToTail_Solution2(ListNode* pListHead, unsigned int k)  
  38. {  
  39.     if(pListHead == NULL)  
  40.         return NULL;  
  41.   
  42.     ListNode *p1, *p2 = pListHead;  
  43.     unsigned int nNum = 1;  
  44.     while(p2 != NULL)  
  45.     {  
  46.         p2 = p2->m_pNext;  
  47.         nNum ++;  
  48.         if(nNum == k) // 结束条件  
  49.             break;  
  50.     }  
  51.     // if the number of nodes in the list is less than k  
  52.     // do nothing  
  53.     if(nNum < k)  
  54.         return NULL;  
  55.     // 现在p1和p2之间的距离保持为k个节点  
  56.     // 同时移动它们,直到p2指向NULL  
  57.     p1 = pListHead;  
  58.     while(p2->m_pNext != NULL)  
  59.     {  
  60.         p1 = p1->m_pNext;  
  61.         p2 = p2->m_pNext;  
  62.     }  
  63.   
  64.     return p1;  
  65. }  
  66.   
  67. void DisplayList(ListNode* pHead)  
  68. {  
  69.     ListNode* p = pHead;  
  70.     if(p == NULL)  
  71.         cout<<"The LinkedList is empty."<<endl;  
  72.     else  
  73.     {  
  74.         while(p != NULL)  
  75.         {  
  76.             cout<<p->m_nKey<<" ";  
  77.             p = p->m_pNext;  
  78.         }  
  79.     }  
  80.     cout<<endl;  
  81. }  
  82.   
  83. void main()  
  84. {  
  85.     Head = pCur = NULL;  
  86.   
  87.     AddToList(pCur, 1);  
  88.     AddToList(pCur, 2);  
  89.     AddToList(pCur, 3);  
  90.     AddToList(pCur, 4);  
  91.     AddToList(pCur, 5);  
  92.     AddToList(pCur, 6);  
  93.     AddToList(pCur, 7);  
  94.   
  95.     DisplayList(Head);  
  96.   
  97.     cout<<"13.求单向链表倒数第k个节点:解二"<<endl;  
  98.     cout<<"The Kth from tail is: "<<FindKthToTail_Solution2(Head, 3)->m_nKey<<endl;  
  99.     system("pause");  
  100. }  
0 0
原创粉丝点击