题目:输入一个链表,输出该链表中倒数第K个节点。为了符合大多数人的习惯,本题从1开始计数,即链表的尾节点是倒数第1个节点。例如一个链表有6个节点,从头节点开始他们的值依次为1,2,3,4,5,6.这个链表的倒数第三个节点是值为4的节点。
分析:不能多次遍历链表,只能一次遍历。
/* 剑指offer面试题15 */ #include <iostream> using namespace std; struct ListNode{ ListNode* Next; int data; }; /* 把题目看错,看成删除了。但是删除功能可以实现, 同样存在和题目一样的问题,存在多次遍历问题。 为了代码质量更好要求只遍历一次。 */ ListNode* DeleteKnode(ListNode** head,int k){ if(*head == NULL || k <= 0){ return NULL; } ListNode* p = *head; ListNode* q = new ListNode; int count = 0; int num = 0; while(p != NULL){ p = p->Next; count++; } //加入k大于链表长度,非法 if(k > count){ return NULL; } //删除尾节点 if(k == 1){ p = *head; int i=1; while(i<(count-1)){ p = p->Next; i++; } q = p->Next; delete q; q = NULL; p->Next = NULL; return *head; } //删除头节点 if(k == count){ p = *head; q = p->Next; delete p; p = NULL; return q; } else{ p = *head; while(p != NULL && (count-k-1) > num){ num++; p = p->Next; } q = p->Next; p->Next = q->Next; delete q; q = NULL; } return p; } void Print(ListNode** head,int k){ if(*head == NULL || k <= 0){ return; } ListNode* first = *head; int length = 0; for(int i=0;i<k-1;++i){ if(first->Next != NULL){ //这是关键步骤!! first = first->Next; length++; } else{ return; } } ListNode* second = *head; while(first->Next != NULL){ first = first->Next; length++; second = second->Next; } cout << second->data << endl; } int main() { ListNode* head = new ListNode; ListNode* One = new ListNode; ListNode* Two = new ListNode; ListNode* tail = new ListNode; head->data = 0; head->Next = One; One->data = 1; One->Next = Two; Two->data = 2; Two->Next = tail; tail->data = 3; tail->Next = NULL; int k; cin >> k; /* ListNode* p = DeleteKnode(&head,k); while(p != NULL){ cout << p->data << " "; p = p->Next; } */ Print(&head,k); return 0; }