首先统一链表的数据结构为:

struct ListNode
{
int val;
struct ListNode *next;
ListNode(int x) :val(x), next(NULL) {}
};

题目一:从尾到头打印链表:输入一个链表。从尾到头打印链表每一个节点的值

分析:

难点在于链表仅仅有指向后继的指针,没有指向前驱的指针。

转换思路。结合栈后进先出的特点,能够遍历链表,依次将数据元素存入栈中,然后再依次出栈,即为从尾到头的顺序。

vector<int> printListFromTailToHead(struct ListNode* head)
{
ListNode *p=head;
stack<int> temp;
while(p)
{
temp.push(p->val);
p=p->next;
}
vector<int>result;
while(!temp.empty())
{
result.push_back(temp.top());
temp.pop();
}
return result;
}

题目二:链表中倒数第k个结点:输入一个链表,输出该链表中倒数第k个结点。

分析:

(1)依据上题的启示。事实上这个题也能够借助栈来完毕。先从头到尾依次将结点存入栈。然后取出从栈顶開始的第k个结点就可以。

(2)还有一种方法是使用先后指针来完毕,一个指针先从头開始向前走k-1步,然后还有一个指针从头開始走。当第一个指针指向最后一个     结点时,后一个指针指向倒数第k个结点。

边界条件:要记得考虑k大于链表长度的情况和k=0的情况都返回空。

方法一:

ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
{
ListNode *p=pListHead;
stack<ListNode*> temp;
int len=0;
while(p)
{
++len;
temp.push(p);
p=p->next;
}
if(len<k||k==0)
return NULL;
while(k!=1)
{
temp.pop();
--k;
}
return temp.top();
}

方法二:

ListNode* FindKthToTail(ListNode* pListHead, unsigned int k)
{
if(pListHead==NULL||k==0)
return NULL;
ListNode *pAhead=pListHead;
ListNode *pBehind=pListHead;
for(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;
}

题目三:反转链表(链表逆序):输入一个链表,反转链表后,输出链表的全部元素。

ListNode* ReverseList(ListNode* pHead)
{
if(!pHead)
return pHead;
ListNode *reverse=NULL;
ListNode *pre=NULL;
ListNode *next=NULL;
ListNode *curr=pHead;
while(curr)
{
next=curr->next;
if(!next)
reverse=curr;
curr->next=pre;
pre=curr;
curr=next;
}
return reverse;
}

题目四:合并两个排序的链表:输入两个单调递增的链表。输出两个链表合成后的链表,当然我们须要合成后的链表满足单调不减规则。

ListNode* Merge(ListNode* pHead1, ListNode* pHead2)
{
ListNode *result=new ListNode(0);
ListNode *r=result;
while(pHead1&&pHead2)
{
if(pHead1->val<=pHead2->val)
{
r->next=pHead1;
r=r->next;
pHead1=pHead1->next; }
else
{
r->next=pHead2;
r=r->next;
pHead2=pHead2->next;
}
}
if(pHead1)
r->next=pHead1;
if(pHead2)
r->next=pHead2;
return result->next;
}

题目五:两个链表的第一个公共结点,输入两个链表,找出它们的第一个公共结点。

分析:两个链表都是单向链表。假设他们有公共的结点,那么这两个链表从某一结点開始,他们的next都指向同一个结点,之后全部的点都重合。不可能再出现分叉。所以它们的拓扑形看起来像一个Y形,而不可能是X形。

方法一:首先遍历两个链表得到它们的长度,就能知道哪个链表长,以及长的链表比短的链表多几个结点。在第二次遍历的时候,在较长的链表上先走相差的步数,接着同一时候在两个链表上遍历。找到的第一个同样的结点就是它们的公共结点。

时间复杂度O(m+n)。不须要辅助栈。

方法二:分别将两个链表存入两个辅助栈中,然后比較两个栈顶的结点是否同样。假设同样,则把栈顶弹出,接着比較下一个栈顶,直到找到最后一个同样的结点。

时间复杂度O(m+n),空间复杂度O(m+n)。

方法一:

ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2)
{
int len1=0,len2=0;
ListNode *p=pHead1,*q=pHead2;
while(p)
{
len1++;
p=p->next;
}
while(q)
{
len2++;
q=q->next;
} if(len1==0||len2==0)
return NULL;
p=pHead1;q=pHead2;
while(len1>len2)
{
p=p->next;
len1--;
}
while(len1<len2)
{
q=q->next;
len2--;
}
while(p!=q)
{
p=p->next;
q=q->next;
}
return p;
}

方法二:

 ListNode* FindFirstCommonNode( ListNode *pHead1, ListNode *pHead2)
{
ListNode *p=pHead1;
ListNode *q=pHead2;
stack<ListNode *> temp1;
stack<ListNode *> temp2;
while(p)
{
temp1.push(p);
p=p->next;
}
while(q)
{
temp2.push(q);
q=q->next;
}
ListNode *result=NULL;
while(!temp1.empty()&&!temp2.empty()&&temp1.top()==temp2.top())
{
result=temp1.top();
temp1.pop();
temp2.pop();
}
return result;
}

题目六:链表中环的入口结点:一个链表中包括环,请找出该链表的环的入口结点。

分析:有两个能够面试的问题:一个题是推断一个链表中。是否有环。

第二个是环的入口结点。

经典方法就是使用快慢指针。快的一次走两步,慢的一次走一步,假设指针重合,说明链表有环。

在此基础上,能够想到,快的比慢的刚好多走了一个环的长度。并且速度是慢的二倍,说明快的总共走的是两个环的长度。慢的总共走了一个环的长度。

所以保持慢指针如今的位置,让快指针再次从头走起。每次走一步,当这次两个指针重合的时候。它们刚好都在环的入口结点上。

推断是否有环的代码:

bool HasLoop(ListNode* pHead)
{
ListNode *slow=pHead,*fast=pHead;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
return true;
}
return false;
}

找环的入口结点代码

ListNode* EntryNodeOfLoop(ListNode* pHead)
{
ListNode *slow=pHead,*fast=pHead;
while(fast&&fast->next)
{
slow=slow->next;
fast=fast->next->next;
if(slow==fast)
{
fast=pHead;
while(fast!=slow)
{
fast=fast->next;
slow=slow->next;
}
return slow;
}
}
return NULL;
}

转载请注明出处:http://blog.csdn.net/xingyanxiao/article/details/47068509

剑指offer——链表相关问题总结的更多相关文章

  1. 剑指Offer 链表中倒数第k个结点

    题目描述 输入一个链表,输出该链表中倒数第k个结点.     思路: 法1:设置2个指针p,q.p先移动k次,然后pq同时后移,p到链表尾尾的时候,q指向倒数第k个节点. 注意://需要考虑k=0,以 ...

  2. 剑指offer——链表中倒数第k个结点

    输入一个链表,输出该链表中倒数第k个结点. class Solution { public: ListNode* FindKthToTail(ListNode* pListHead, unsigned ...

  3. 剑指Offer——链表中环的入口结点

    题目描述: 一个链表中包含环,请找出该链表的环的入口结点. 分析: 设置两个指针p1,p2, 两个指针都从链表的头部开始走,不过p1每次走一步,p2每次走两步. 直到相遇的时候,p2走的长度是p1的两 ...

  4. 剑指Offer——链表中倒数第k个节点

    Question 输入一个链表,输出该链表中倒数第k个结点. Solution 一种想法就是扫描两边,第一遍求出总的节点个数,第二遍从头开始走n-k个 第二种思想类似于fast-slow指针的方法,f ...

  5. python剑指offer 链表中环的入口节点

    题目: 一个链表中包含环,请找出该链表的环的入口结点. 思路: 先说个定理:两个指针一个fast.一个slow同时从一个链表的头部出发, fast一次走2步,slow一次走一步,如果该链表有环,两个指 ...

  6. acwing 70-72 剑指OFFER 二叉树相关

    地址 https://www.acwing.com/problem/content/66/ https://www.acwing.com/problem/content/67/ https://www ...

  7. 用js刷剑指offer(链表中倒数第k个结点)

    题目描述 输入一个链表,输出该链表中倒数第k个结点. 牛客网链接 思路 设置两个指针,p,q,先让p走k-1步,然后再一起走,直到p为最后一个 时,q即为倒数第k个节点 js代码 // 空间复杂度1 ...

  8. 剑指offer 链表中环的入口位置

    题目描述 一个链表中包含环,请找出该链表的环的入口结点.   思路:这题需要知道a = c,然后head和slow每次走一步,相遇的时候就是第一个入口交点, 注意:for循环或者while循环之后,一 ...

  9. 剑指offer 链表中倒数第K个节点

    利用两个间隔为k的指针来实现倒数第k个 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 ...

随机推荐

  1. mysql case when使用记录

    两种实现方式 第一种,CASE后面跟字段,当等于WHEN后面的值时,输出指定的数据 SELECT CASE gc.cat_id THEN '台球' THEN '羽毛球' ELSE '其它' END A ...

  2. YV12 NV12区别

    用videoCapture和IAMStreamConfig拿到的支持的格式列表.发现支持2中图像格式,YV12和NV12.具体是怎么样的内存分布不知道.查了些文档.自己修改了几个图.看出了点端倪 YV ...

  3. YYH的积木(NOIP模拟赛Round 6)

    题目描述 YYH手上有n盒积木,每个积木有个重量.现在他想从每盒积木中拿一块积木,放在一起,这一堆积木的重量为每块积木的重量和.现在他想知道重量最少的k种取法的重量分别是多少. 输入输出格式 输入格式 ...

  4. springMVC多图片压缩上传的实现

    首先需要在配置文件中添加配置: <!--配置文件的视图解析器,用于文件上传,其中ID是固定的:multipartResolver--> <bean id="multipar ...

  5. shiro配置参考(一)

    <?xml version="1.0" encoding="UTF-8"?> <beans xmlns:xsi="http://ww ...

  6. IE浏览器对虚拟主机配置域名的问题

    之前一直搞不明白web开发做本地调试的时候IE浏览器老是无法登陆,而谷歌和其他内核浏览器能正常登陆的问题,后来发现IE浏览器对WEB服务器配置的虚拟主机域名规则是不能包含这个'_'下划线符号的,否则会 ...

  7. C#实时读取数据----局部页面刷新【转】

    I)现在刚开始学习C#,对一些基本的控件了解的不够,有个实时监控的系统,需要页面中的数据每5秒钟刷新一次, 要是每5秒钟页面全部的刷新,那页面根本就没法看了,对这个问题在CSDN上也专门开了帖子,问了 ...

  8. 第二部分:Spring中配置mongodb

    一.需要引用的jar包 1.spring-data-mongodb-1.9.4.RELEASE.jar 2.spring-data-commons-1.12.11.RELEASE.jar 3.mong ...

  9. Selenium2+python自动化1-环境搭建【转载】

    前言 目前selenium版本已经升级到3.0了,网上的大部分教程是基于2.0写的,所以在学习前先要弄清楚版本号,这点非常重要.本系列依然以selenium2为基础,目前selenium3坑比较多,暂 ...

  10. pandas read excel文件碰到的一个小问题

    今天利用pandas读取excel时,爆出如下错误: 代码为: import pandas as pd db_eua=pd.read_excel('db_eua.xlsx',sheetname='EU ...