题目:输入一个链表,输出该链表中倒数第k个结点
思路:1.遍历两遍链表,第一遍找到链表长度n,第二遍从0到n-k+1找到倒数第k个节点,不是最优解。
2.使用两个指针,只需遍历一遍链表。第一个指针先走k-1步,然后两个指针同时向后遍历,当第一个指针走到尾节点时,第二个指针刚好在倒数第k个节点上。
注意:代码的鲁棒性!!
链表为空,k为0,k大于链表长度的情况下应该返回NULL
思路1
#include <iostream> #include <malloc.h> using namespace std; typedef struct Node { int val; struct Node* next; }ListNode; ListNode* FindKthToTail(ListNode* pListHead, unsigned int k) { if(pListHead == NULL || k == 0)return NULL; ListNode* p = pListHead; ListNode* q = pListHead; int count = 0; while(p->next != NULL) { p = p->next; count++; } int n = count-k+1; if(n <= 0)return NULL; for(int i = 0;i < n;i++) { q = q->next; } return q; } int main() { int n,num; ListNode* pHead = (ListNode*)malloc(sizeof(ListNode)); pHead->next = NULL; cin>>n; ListNode* pTail = pHead; while(n--) { ListNode* p = (ListNode*)malloc(sizeof(ListNode)); cin>>num; p->val = num; p->next = NULL; pTail->next = p; pTail = p; } ListNode* node = FindKthToTail2(pHead,3); cout<<node->val<<endl; }
思路2
#include <iostream> #include <malloc.h> using namespace std; typedef struct Node { int val; struct Node* next; }ListNode; ListNode* FindKthToTail2(ListNode* pListHead, unsigned int k) { if(pListHead == NULL || k == 0)return NULL; ListNode* pAhead = pListHead; ListNode* pBehind = pListHead; for(unsigned int i = 0;i < k-1;i++) { if(pAhead->next != NULL) pAhead = pAhead->next; else{ return NULL; } } while(pAhead->next != NULL) { pAhead = pAhead->next; pBehind = pBehind->next; } return pBehind; } int main() { int n,num; ListNode* pHead = (ListNode*)malloc(sizeof(ListNode)); pHead->next = NULL; cin>>n; ListNode* pTail = pHead; while(n--) { ListNode* p = (ListNode*)malloc(sizeof(ListNode)); cin>>num; p->val = num; p->next = NULL; pTail->next = p; pTail = p; } ListNode* node = FindKthToTail2(pHead,3); cout<<node->val<<endl; }