给定一个有环链表,实现一个算法返回环路的开头结点
2016-11-16 00:00
363 查看
由于如果两个链表如果相交,那么交点之后node都是共享(地址相同)的,因此最简单暴力的方法就是两个for循环,判断该链表的node是否属于另外一个链表。但是这个算法复杂度是O(length1 * length2)。如果链表较长,这个复杂度有点高了。
当然也可以遍历其中某个链表,将node的地址存储hash table中;然后接下来遍历另外一个链表,查找node是否在这个hash table中。这样的话时间复杂度就是O(length1 + length2)。但是需要额外的O(length1)的空间。
/**
* 功能:给定一个有环链表,实现一个算法返回环路的开头结点。
*/
/**
* 思路:fast的移动速度是slow的两倍。当slow走了k个结点进入环路,fast已经进入环路k个结点,即fast和slow
* 相距loop_size -k个结点。
* 再走loop_ -k次后,碰撞,此时距离环路起始处k个结点。
* 链表首部与环路起始处均距离环路起始处k个结点。因此,保持其中一个不变,另一个指向链表首部,相会处
* 即为环路起始处。
*
* 算法:
* 1)创建两个指针,fast和slow。
* 2)slow每走一步,fast走两步。
* 3)碰撞时,将slow指向head,fast保持不变。
* 4)相同速度移动fast和slow,一次一步,返回碰撞结点。
* @param head
* @return
*/
public static LinkedListNode findBeginging(LinkedListNode head){
LinkedListNode slow= head;
LinkedListNode fast= head;
while( fast!= null&& fast. next!= null){
slow= slow. next;
fast= fast. next. next;
if( slow!= fast)
break;
}
if( fast== null|| fast. next== null)
return null;
slow= head;
while( slow!= fast){
slow= slow. next;
fast= fast. next;
}
return fast;
}
当然也可以遍历其中某个链表,将node的地址存储hash table中;然后接下来遍历另外一个链表,查找node是否在这个hash table中。这样的话时间复杂度就是O(length1 + length2)。但是需要额外的O(length1)的空间。
/**
* 功能:给定一个有环链表,实现一个算法返回环路的开头结点。
*/
/**
* 思路:fast的移动速度是slow的两倍。当slow走了k个结点进入环路,fast已经进入环路k个结点,即fast和slow
* 相距loop_size -k个结点。
* 再走loop_ -k次后,碰撞,此时距离环路起始处k个结点。
* 链表首部与环路起始处均距离环路起始处k个结点。因此,保持其中一个不变,另一个指向链表首部,相会处
* 即为环路起始处。
*
* 算法:
* 1)创建两个指针,fast和slow。
* 2)slow每走一步,fast走两步。
* 3)碰撞时,将slow指向head,fast保持不变。
* 4)相同速度移动fast和slow,一次一步,返回碰撞结点。
* @param head
* @return
*/
public static LinkedListNode findBeginging(LinkedListNode head){
LinkedListNode slow= head;
LinkedListNode fast= head;
while( fast!= null&& fast. next!= null){
slow= slow. next;
fast= fast. next. next;
if( slow!= fast)
break;
}
if( fast== null|| fast. next== null)
return null;
slow= head;
while( slow!= fast){
slow= slow. next;
fast= fast. next;
}
return fast;
}
相关文章推荐
- 9.2链表(六)——给定一个有环链表,实现一个算法返回环路的开头结点
- 给定一个有环链表,实现一个算法返回环路的开头结点
- 【Java】给定一个有环链表,实现算法返回环路的开头结点
- 010给定一个循环链表,实现一个算法返回这个环的开始结点 (keep it up)
- 给定一个循环链表,实现一个算法返回这个环的开始结点
- 程序员面试金典: 9.2链表 2.6给定有环链表,实现算法返回环路的开头节点
- 有一棵二叉树,请设计一个算法,按照层次打印这棵二叉树。 给定二叉树的根结点root,请返回打印结果,
- 请实现一个算法,确定一个字符串的所有字符是否全都不同。这里我们要求不允许使用额外的存储结构。 给定一个string iniString,请返回一个bool值,True代表所有字符全都不同,False代
- 给定一棵二叉树,设计一个算法,创建含有某一深度上所有结点的链表(比如:若一棵树的深度为D,则会创建出D个链表)
- 输入一组整型元素序列,使用尾插法建立一个带有头结点的单链表。 ② 实现该线性表的遍历。 ③ 在该单链表的第i个元素前插入一个整数。 ④ 删除该单链表中的第i个元素,其值通过参数将其返回。 ⑤ 建立两个
- 有一堆扑克牌,其中某张牌的张数超过了扑克牌总数的一半,请找到这张牌。写出算法思路、代码实现和算法的时间复杂度,要求算法尽可能高效。假设给定一个扑克牌的数组poker和它的大小n,请返回所求的扑克牌。
- 原串翻转 请实现一个算法,在不使用额外数据结构和储存空间的情况下,翻转一个给定的字符串(可以使用单个过程变量)。 给定一个string iniString,请返回一个string,为翻转后的字符串
- 请实现一个算法,在不使用额外数据结构和储存空间的情况下,翻转一个给定的字符串(可以使用单个过程变量)。 给定一个string iniString,请返回一个string,为翻转后的字符串。保证字符串的
- 编写算法实现建立一个带头结点的含n个元素的双向循环链表H,并在链表H中的第i个位置插入一个元素e
- 链式A+B有两个用链表表示的整数,每个结点包含一个数位。这些数位是反向存放的,也就是个位排在链表的首部。编写函数对这两个整数求和,并用链表形式返回结果。 给定两个链表ListNode* A,ListN
- 链表分割 编写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 给定一个链表的头指针 ListNode* pHead,请返回重新排列后的链表的头指针。注意:分割以
- 给定一个单向链表(长度未知),请设计一个既节省时间又节省空间的算法来找出该链表中的倒数第m个元素。实现这个算法,并为可能出现的特例情况安排好处理措施。“倒数第m个元素”是这样规定的:当m=0时,链表的
- 题目:给定单向链表的头指针和一个结点指针,定义一个函数在O(1)时间删除该结点。
- LinkLists 删除链表中的一个给定指针的结点 @CareerCup
- 数据结构——算法之(004)(输入一个单向链表,输出该链表中倒数第k个结点)