…7、8、9主要考虑代码的鲁棒性问题…
7、剑指offer15:链表中倒数第k个结点
原理:倒数第K个结点就是从头结点开始的第n-k+1个结点,为了实现一次遍历就找到倒数第k个结点:定义两个指针,第一个指针从头指针先走K-1步,第二个指针不动;从第k补开始,第二个指针也开始从头指针遍历,两个指针一起走,当第一个指针走到尾结点时,第二个指针的位置则为n-k+1,正好为倒数第k个结点。
此代码注意三种情况:(考查代码的鲁棒性)
(1)输入的pHead为空指针时;
(2)输入的参数k为0时,k-1不是-1,而是0XFFFFF…;
(3)输入的以pHead为头结点的链表的结点总数小于K。
ListNode* Findkth(ListNode* pHead,unsigned int k)
{
if(pHead==NULL||k==0)
{
cout<<"error,return NULL!"<<endl;
return NULL; //情况(1)和(2)
}
ListNode* pAhead=pHead;
ListNode* pBehind=NULL;
for(int i=1;i<k;i++)
{
if(pAhead->m_pnext!=NULL)
pAhead=pAhead->m_pnext;
else
{
cout<<"error,return NULL!"<<endl;
return NULL; //情况(3)
}
}
pBehind=pHead;
while(pAhead->m_pnext!=NULL)
{
pAhead=pAhead->m_pnext;
pBehind=pBehind->m_pnext;
}
return pBehind;
}
8、剑指offer16:反转链表,整个链表反转
ListNode* ReverList(ListNode* pHead)
{
ListNode* pre=NULL;
ListNode* pNode=pHead;
ListNode* pReverHead=NULL;//反转后链表的头结点
while(pNode!=NULL)
{
ListNode* pNext=pNode->m_pnext;
if(pNext==NULL)
pReverHead=pNode;
pNode->m_pnext=pre;
pre=pNode;
pNode=pNext;
}
return pReverHead;
}
***8.1、反转链表,(从m到n)*** 亲测可用
https://blog.youkuaiyun.com/Alpaca12/article/details/51508916
9、剑指offer17:合并两个排序的链表
题目:输入两个递增排序的链表,合并这两个链表并使新链表中的结点仍然是按照递增排序的。
ListNode* Merge(ListNode* pHead1,ListNode* pHead2)
{
if(pHead2=NULL)
return pHead1;
else if(pHead1=NULL)
return pHead2;
ListNode* pMergeHead=NULL;
if(pHead1->m_value<pHead2->m_value)
{
pMergeHead=pHead1;
pMergeHead->m_pnext=Merge(pHead1->m_pnext,pHead2);
}
else
{
pMergeHead=pHead2;
pMergeHead->m_pnext=Merge(pHead1,pHead2->m_pnext);
}
return pMergeHead;
}
…7、8、9主要考虑代码的鲁棒性问题…
10、剑指offer37:找出两个链表的第一个公共结点
原理:如果两个链表有公共结点,则呈现出“Y”型结构,我们采用的方法是:首先遍历两个链表得到他们的长度,就能知道哪个链表比较长,并且知道长的链表比短的链表多几个结点,假设s个结点;在第二次遍历的时候,在较长的链表上先走s步,接着再同时在两个链表上遍历,找到的第一个相同的结点就是他们的第一个公共结点。
该方法的时间效率为O(m+n)l;m和n分别为两个链表的长度
https://blog.youkuaiyun.com/xiaxzhou/article/details/74356743