笔试算法题(27):判断单向链表是否有环并找出环入口节点 & 判断两棵二元树是否相等
出题:判断一个单向链表是否有环,如果有环则找到环入口节点;
分析:
- 第一个问题:使用快慢指针(fast指针一次走两步,slow指针一次走一步,并判断是否到达NULL,如果fast==slow成立,则说明链表有环);
- 第二个问题:fast与slow相遇时,slow一定还没有走完一圈(反证法可证明);
示意图 A为起始点,B为环入口点,C为相遇点,则a1=|AB|表示起始点到换入口的距离,a2=|CB|表示相遇点到环入口点的距离,s1=|AB|+|BC|表示slow指针走的长度,s2表示fast指针走的长度,C=|BCB|表示环的长度
由于fast的速度是slow的2倍,所以相遇的时候走过的长度也是2倍
s2=2*s1=a1+N*C+(s1-a1) (1)
N表示fast在环中走的圈数,化解(1)得到:
s1=N*C (2)
找到a1和a2的关系:
a2=C-(s1-a1) (3)
将(2)代入(3)得到:
a1=a2+(N-1)*C (4)
所以如果指针m从起始点A出发,指针n从相遇点C出发,n绕行(N-1)圈环之后最终跟m指针在B点相遇
解题:
struct Node {
int v;
Node *next;
};
Node* IsCycle(Node *head) {
Node *fast=head, *slow=head; while(true) {
if(fast!=NULL)
fast=fast->next;
if(fast!=NULL)
fast=fast->next;
else
return NULL;
if(slow!=NULL)
slow=slow->next;
else
return NULL; if(fast==slow)
return fast;
}
}
Node* FindEntry(Node *head, Node *joint) {
Node *m=head, *n=joint;
while(true) {
if(m==n)
return m;
m=m->next;
n=n->next;
}
}
int main() {
Node* b1=new Node(); b1->v=;
Node* b2=new Node(); b2->v=;b1->next=b2;
Node* b3=new Node(); b3->v=;b2->next=b3;
Node* b4=new Node(); b4->v=;b3->next=b4;
Node* b5=new Node(); b5->v=;b4->next=b5;
Node* b6=new Node(); b6->v=;b5->next=b6;
Node* b7=new Node(); b7->v=;b6->next=b7;
Node* b8=new Node(); b8->v=;b7->next=b8; b8->next=b3; Node* temp;
if((temp=IsCycle(b1))!=NULL) {
printf("\nthe joint point is: %d",temp->v);
printf("\nthe entry of cycle is: %d",FindEntry(b1,temp)->v);
}
else
printf("\nthere is no cycle.");
return ;
}
出题:判断两棵二元树是否相等(左右子树不能交叉比较);
分析:使用递归实现,在树的K层,有2^K 个节点,所以会进行(2^K)*2次调用,所以时间复杂度为O(N);
解题:
struct Node {
int value;
Node *left;
Node *right;
}; bool CompareTree(Node *first, Node *second) {
if(first==NULL && second==NULL)
return true;
if((first==NULL && second!=NULL) ||
(first!=NULL && second==NULL))
return false;
if(first->value!=second->value)
return false;
return CompareTree(first->left,second->left) &&
CompareTree(first->right, second->right);
}
笔试算法题(27):判断单向链表是否有环并找出环入口节点 & 判断两棵二元树是否相等的更多相关文章
- 笔试算法题(25):复制拥有多个指针的链表 & 判断二元树B是否为A的子树
出题:定义一个复杂链表:在单向链表的基础上,每个节点附加一个指向链表中其他任意节点的指针sibling,实现CNode* Clone(Cnode *head)函数复制这个复杂链表: 分析: 解法1:将 ...
- 【算法题 14 LeetCode 147 链表的插入排序】
算法题 14 LeetCode 147 链表的插入排序: 解题代码: # Definition for singly-linked list. # class ListNode(object): # ...
- 判断单链表是否有环,并找出环的入口python
1.如何判断一个链表是否有环? 2.如果链表为存在环,如果找到环的入口点? 1.限制与要求 不允许修改链表结构. 时间复杂度O(n),空间复杂度O(1). 2.思考 2.1判断是否有环 如果链表有环, ...
- 笔试算法题(19):判断两条单向链表的公共节点 & 字符集删除函数
出题:给定两个单向链表的头结点,判断其是否有公共节点并确定第一个公共节点的索引: 分析: 由于是单向链表,所以每个节点有且仅有一个后续节点,所以只可能是Y型交叉(每条链表中的某个节点同时指向一个公共节 ...
- 数据结构和算法之单向链表二:获取倒数第K个节点
我们在做算法的时候或多或少都会遇到这样的问题,那就是我们需要获取某一个数据集的倒数或者正数第几个数据.那么今天我们来看一下这个问题,怎么去获取倒数第K个节点.我们拿到这个问题的时候自然而然会想到我们让 ...
- 前端如何应对笔试算法题?(用node编程)
用nodeJs写算法题 咱们前端使用算法的地方不多,但是为了校招笔试,不得不针对算法题去练习呀! 好不容易下定决心 攻克算法题.发现js并不能像c语言一样自建输入输出流.只能回去学习c语言了吗?其实不 ...
- 笔试算法题(58):二分查找树性能分析(Binary Search Tree Performance Analysis)
议题:二分查找树性能分析(Binary Search Tree Performance Analysis) 分析: 二叉搜索树(Binary Search Tree,BST)是一颗典型的二叉树,同时任 ...
- 笔试算法题(57):基于堆的优先级队列实现和性能分析(Priority Queue based on Heap)
议题:基于堆的优先级队列(最大堆实现) 分析: 堆有序(Heap-Ordered):每个节点的键值大于等于该节点的所有孩子节点中的键值(如果有的话),而堆数据结构的所有节点都按照完全有序二叉树 排.当 ...
- 笔试算法题(38):并查集(Union-Find Sets)
议题:并查集(Union-Find Sets) 分析: 一种树型数据结构,用于处理不相交集合(Disjoint Sets)的合并以及查询:一开始让所有元素独立成树,也就是只有根节点的树:然后根据需要将 ...
随机推荐
- (转)Silverlight_5_Toolkit_December_2011 安装后点击Toolkit Samples没反应的解决方法
Silverlight Toolkit官方下载地址: http://silverlight.codeplex.com/ http://blog.csdn.net/hcj116/article/deta ...
- jquery cloudzoom 3.0,magiczoom 放大镜插件 破解 移除版权信息
jquery Cloud Zoom一款放大镜插件.但是无奈 官方下载的始终有版权信息,因此想到如下方法去掉版权信息,测试可行! 官方网址:http://www.starplugins.com/clou ...
- Linux下安装Redis及搭建主从
Linux下安装Redis 首先在官网下载对应版本的redis包,这里本人使用的是redis-4.0.8.tar.gz. 然后在服务器中存放redis包的路径下执行tar –vxf redis-4 ...
- E20170516-gg
accelerator n. 加速器;油门 oscillator n. 振荡器; 振子; oscillate vt. 使振荡,使振动 vi. 持续周期性地摆动; frame n. 框架; 边 ...
- Codeforces Round #382 (Div. 2) (模拟|数学)
题目链接: A:Ostap and Grasshopper B:Urbanization C:Tennis Championship D:Taxes 分析:这场第一二题模拟,三四题数学题 A. 直接模 ...
- 最小割树Gomory–Hu tree
fanhq666地址:http://fanhq666.blog.163.com/blog/static/8194342620113495335724/ wiki地址(证明):https://en.wi ...
- spoj 1693 COCONUTS - Coconuts【最小割】
s向所有信仰1的人连(s,i,1),所有信仰0的人连(i,t,1),对于朋友关系,连接双向边,流量为1.跑最大流的结果即为答案. 考虑这样做的意义.最小割就是把总点集分割为两个点集S,T,使得所有\( ...
- Android Studio编写运行测试纯java代码可带main()函数
问题 小伙伴们在做安卓项目的时候,是不是有时候会忘记某些api的使用方法,不太确定他们的结果是怎样的,需要写一些测试代码,验证看看我们的写法是否正确.刚开始的时候我是在页面上写一个Button,添加点 ...
- Kubernetes集群认证
1.集群搭建:https://www.kubernetes.org.cn/3808.html 2.集群验证:https://www.kubernetes.org.cn/1861.html
- 数据结构 - 顺序栈的实行(C语言)
数据结构-顺序栈的实现 1 顺序栈的定义 既然栈是线性表的特例,那么栈的顺序存储其实也是线性表顺序存储的简化,我们简称为顺序栈.线性表是用数组来实现的,对于栈这种只能一头插入删除的线性表来说,用数组哪 ...