返回环路的开头结点

给定一个有环链表,实现一个算法返回环路的开头结点。

#include<iostream>

using namespace std;

typedef struct node

{

int data;

struct node* next;

}* LinkedListNode;

LinkedListNode FindBeginning(LinkedListNode head)

{

LinkedListNode slow = head;

LinkedListNode fast = head;

//找出碰撞处,将处于链表LOOP_SIZE-k步的位置

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指向首部,fast指向碰撞处,两者距离环路起始处k步,

//若两者以相同速度前进,则必定会在环路起始位置碰撞在一起

slow = head;

while (slow != fast)

{

slow = slow->next;

fast = fast->next;

}

//至此两者均指向环路起始处

return fast;

}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-16 16:56:06

返回环路的开头结点的相关文章

2.6给定一个有环链表,实现一个算法返回环路的开头结点。

书上写的好复杂. 1.检测链路是否存在环路.通过FastRunner/SlowRunner法,FastRunner一次移动两步,SlowRunner一次移动一步. 2.当二者碰到之后,F继续走,S从头走.当他们再次碰头时,那就是环的入口. 建议:空想好难,建议随便列几个数字看看规律. LinkedListNode FindBeginning(LinkedListNode head) { LinkedListNode slow = head; LinkedListNode fast = head;

给定一个链表,删除链表的倒数第 n 个节点(已知该结点存在),并且返回链表的头结点。

思路: 找到倒数第n个结点的前一个结点,让该结点的后继为倒数第n个结点的后继 子问题:找到倒数第n个结点的前驱 1.有两个引用,第一个引用指向首节点,然后走n步 2.第二个结点指向首节点,此时两结点之间隔了n-1个结点,保持这样的距离,共同向后移动 3.当第一个引用到达尾节点时,第二个引用离尾节点有n-1个结点, 4.此时第二个结点为倒数第n+1个结点,即倒数第n个结点的前驱 特殊情况: 1.链表只有一个结点或者为空链表,直接返回空即可: 2.链表的长度刚好等于n,即删除首节点,第一个引用从头结

2.6---找有环链表的开头结点(CC150)

public ListNode detectCycle(ListNode head) { ListNode fast = head; ListNode slow = head; int flag = 0; ListNode intersection = null; while(fast != null && fast.next != null){ fast = fast.next.next; slow = slow.next; if(fast == slow){ intersection

careercup-链表 2.6

2.6 给定一个有环链表,实现一个算法返回环路的开头结点. 类似leetcode中 Linked List Cycle II C++实现代码: #include<iostream> #include<new> using namespace std; struct ListNode { int val; ListNode *next; ListNode(int x):val(x),next(NULL) {} }; void createList(ListNode *&L)

【Cracking the Code Interview(5th edition)】二、链表(C++)

链表结点类型定义: 1 class Node { 2 public: 3 int data = 0; 4 Node *next = nullptr; 5 6 Node(int d) { 7 data = d; 8 } 9 }; 快行指针(runner)技巧: 同时使用两个指针来迭代访问链表,其中一个比另一个超前一些.快指针比慢指针先行几步或者快指针与慢指针的速度呈一定的关系. dummy元素技巧: 在链表头部添加一个哑结点,通常可以简化首部或尾部的特殊情况的处理. 2.1 编写代码,移除未排序链

链表常见题型(java版)

直接上干货..... 链表常见题型: 找到单链表的倒数第k个节点. 删除单链表中的某个结点(O(1)). 反转链表. 两个链表的第一个公共结点. 有环链表返回环路的开头节点(及判断是否有环). 合并两个排序的链表. 删除链表中重复的结点. 先给出链表的定义: /** * 单链表定义 */ public static class Node<E>{ private E element;//节点保存的元素 private Node<E> next;//指向下一个节点的引用 public

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回

题目:给定一个二叉树其中的一个结点(此节点可以为二叉树任意一个节点),请找出中序遍历顺序的下一个结点并且返回.注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针. 此二叉树的中序遍历为:8.4.9.2.10.5.1.6.3.7 思路: (1)如果此结点有右结点:返回 此结点的右结点 的最左的结点(例如4.2) (2)如果此结点没有右结点:(1)此结点为根节点:返回None  (2)此结点为上一个结点的左节点:返回上一个结点(例如结点6.8)  (3)此结点为上一个结点的右节点:(1)此

第25章:所有结点对的最短路径问题—floyd-warshall和Johnson算法

二:Floyd-Warshall算法 该算法适用于边权重可以为负值,但环路权重和不能为负值的图,其运行时间为Θ(V3). 假设dkij为从结点i到结点j的所有中间结点全部取自集合{1,2,-,k}的一条最短路径权重.当k=0时,从结点i到结点j的一条不包括编号大于0的中间结点的路径将没有任何中间结点.这样的路径最多只有一条边,因此d(0)ij=wij.因此如果k=0,dkij=wij,若k>=1,则dkij=min(d(k?1)ij,d(k?1)ik+d(k?1)kj). 另外,我们可以在计算最

C++学习笔记47:链表的概念与结点类模板

学堂在线学习笔记 链表的概念与结点类模板 顺序访问的线性群体--链表类 链表是一种动态数据结构,可以用来表示顺序访问的线性群体: 链表是由系列结点组成,结点可以在运行时动态生成: 每一个结点包括数据域和指向链表中下一个结点的指针(即下一个结点的地址).如链表中每个结点中只有一个指向后继结点的指针,则该链表称为单链表: 单链表的结点类模板 template <class T> void Node<T>::insertAfter(Node<T> *p) { //p结点指针域