题目:输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。(尾节点为倒数第0个节点,有头节点,头节点数据为空,尾节点数据不为空)
链表结点定义如下:
- struct ListNode
- {
- int m_nKey;
- ListNode* m_pNext;
- };
思路一:遍历整个链表,找到链表中节点的个数,根据节点个数能够确定倒数第k个节点从头开始数的序号,从而找到倒数第k个节点
- ListNode *Find(ListNode* head,int k)
- {
- int num=0;//除去头 节点个数
- ListNode *now=head;
- while(now->m_pNext!=NULL)
- {
- now=now->m_pNext;
- num++;
- }
- if(num<k)
- return NULL;
- now=head;
- for(int i=0;i<num-k;i++)
- now=now->m_pNext;
- return now;
- }
思路二:如果我们在遍历时维持两个指针,第一个指针从链表的头指针开始遍历,在第k-1步之前,第二个指针保持不动;在第k-1步开始,第二个指针也开始从链表的头指针开始遍历。由于两个指针的距离保持在k-1,当第一个(走在前面的)指针到达链表的尾结点时,第二个指针(走在后面的)指针正好是倒数第k个结点。
- ListNode * Find2(ListNode *head,int k)
- {
- ListNode *ahead=head;
- ListNode *after=head;
- for(int i=0;i<k;i++)
- {
- if(ahead->m_pNext!=NULL)
- ahead=ahead->m_pNext;
- else
- return NULL;
- }
- while(ahead->m_pNext!=NULL)
- {
- ahead=ahead->m_pNext;
- after=after->m_pNext;
- }
- return after;
- }
- void main()
- {
- ListNode a[7];
- a[0].m_pNext=&a[1];
- a[1].m_nKey=1;
- a[1].m_pNext=&a[2];
- a[2].m_nKey=2;
- a[2].m_pNext=&a[3];
- a[3].m_nKey=3;
- a[3].m_pNext=&a[4];
- a[4].m_nKey=4;
- a[4].m_pNext=&a[5];
- a[5].m_nKey=5;
- a[5].m_pNext=&a[6];
- a[6].m_nKey=6;
- a[6].m_pNext=NULL;
- cout<<Find(&a[0],1)->m_nKey<<endl;
- }