题目:输入一个链表,输出该链表的倒数第K个结点。为了符合大多数人的习惯,本题
从1开始计数,即链表的尾结点是倒数第1个节点。例如有一个链表有6个节点,从
头节点开始他们的值依次是1,2,3,4,5,6.这个链表的倒数第三个节点是值为4的节点。
这个题目常规情况下我们都是考虑先从链表的头遍历到链表的尾,然后后退k步取倒数第
k个节点的值。
然而我们也可以这样考虑先遍历一遍链表计算出链表的长度N,要取出倒数的第k个,其实就是
从链表头走N-k+1步便到了倒数第k个节点,但是这种方式似乎并没有什么改进。
然而我们可以举这样一个例子3->2->4->5->9->6我们要取出倒数第三个元素即值为5的元素
我们可以设置两个指针ptr1和ptr2这两个指针开始都指向3,然后ptr1向后移动k-1步即移动到第四
个元素的位置。这时候ptr1和ptr2再同时移动知道ptr1指向最后一个元素,这时候ptr正好指向5
两个指向之间相差正好k-1个元素。
代码实现如下:
1 #include <iostream> 2 #include <stack> 3 using namespace std; 4 5 struct ListNode 6 { 7 int data; 8 struct ListNode *next; 9 }; 10 11 struct ListNode* CreateList() 12 { 13 struct ListNode* Head,*p; 14 Head=(struct ListNode*)malloc(sizeof(ListNode)); 15 Head->data=0; 16 Head->next=NULL; 17 p=Head; 18 19 cout<<"Create List....(0-exit!)"<<endl; 20 while(true) 21 { 22 int Data; 23 cin>>Data; 24 if(Data!=0) 25 { 26 struct ListNode* NewNode; 27 NewNode=(struct ListNode*)malloc(sizeof(ListNode)); 28 NewNode->data=Data; 29 NewNode->next=NULL; 30 p->next=NewNode; 31 p=p->next; 32 } 33 else 34 { 35 break; 36 } 37 } 38 39 return Head->next; 40 } 41 42 void PrintList(struct ListNode* Head) 43 { 44 cout<<"The List is: "; 45 46 struct ListNode *p; 47 p=Head; 48 while(p!=NULL) 49 { 50 cout<<p->data<<" "; 51 p=p->next; 52 } 53 cout<<endl; 54 } 55 56 ListNode* FindKthToTail(ListNode* pListHead,unsigned int k) 57 { 58 ListNode *ptr1,*ptr2; 59 ptr1=pListHead; 60 ptr2=pListHead; 61 62 if(pListHead==NULL||k==0) 63 return NULL; 64 65 int count=0; 66 /* while(count<=(k-1)) 67 { 68 ptr1=ptr1->next; 69 count++; 70 }*/
//未考虑到当k大于链表本身的长度
改:
while(count<=(k-1))
{
if(ptr1->next==NULL)
{
return NULL;
}
else
{
ptr1=ptr1->next;
count++;
}
}
71 72 while(ptr1!=NULL) 73 { 74 ptr1=ptr1->next; 75 ptr2=ptr2->next; 76 } 77 78 79 return ptr2; 80 } 81 82 83 int main() 84 { 85 ListNode *Head; 86 Head=CreateList(); 87 PrintList(Head); 88 if(FindKthToTail(Head,3)) 89 { 90 cout<<"Last K value in List is: "<<FindKthToTail(Head,3)->data<<endl; 91 } 92 return 0; 93 }
运行截图: