【CareerCup】 Linked Lists—Q2.5
转载请注明出处:http://blog.csdn.net/ns_code/article/details/22097191
题目:
Given a circular linked list, implement an algorithm which returns node at the beginning of the loop.
DEFINITION
Circular linked list: A (corrupt) linked list in which a node’s next pointer points to an earlier node, so as to make a loop in the linked list.
EXAMPLE
Input: A -> B -> C -> D -> E -> C [the same C as earlier]
Output: C
翻译:
给定一个循环链表,实现一个算法返回这个环的开始结点。
定义:
循环链表:链表中一个结点的指针指向先前已经出现过的某个结点,导致链表中出现环。
示例:
输入:A -> B -> C -> D -> E -> C [结点C在之前已经出现过]
输出:结点C
思路:
最直观且容易理解的方法(借鉴编程之美上的思路)是:
设两个指针p1和p2,一个移动速度快(每次移动两个节点的距离),一个移动速度慢(每次移动一个节点的距离),刚开始均指向表头,如果链表中存在环,则快指针最终会追上慢指针。二者遇的节点肯定是环中的一个节点,此时我们固定其中一个指针p1,而后以每次一个节点的速度移动p2,记录下p2最终又回到p1所在节点位置时走过的节点数M,M即为环中节点的个数。而后我们再将两个指针同时指向表头,先固定p1,让p2以每次一个节点的速度移动M个节点,而后让p1和p2同时移动,这样当p1刚到环入口时,p2刚好转了一圈回到环入口,因此二者相遇的节点便是环开始的节点。
Hawstein的blog中给出了另外两种方法,一种也是设置上面两个指针来分析的,貌似有点繁琐,没仔细看。另一种用哈希表,这个我也想到了,但是感觉没法恰当地契合,而且用地址做哈希表的键值,对内存貌似有很大的浪费哦,所以感觉这个不算是个很好的方法!另外,对C++也不熟啊!哎。。。搞java的人伤不起啊!
我还想了另外一种方法,在链表中多加一个域(这种方法可能很离谱,就好像给你个问题去解决,你把问题的参数给改了,然后再去解决它,但我觉得可以作为解决一些问题的思路,其实依然有哈希的思想在里面),如下:
typedef struct Node
{ElemType data;bool flag;struct Node *next;
}
建链表时,flag全部置为false,而后从头遍历时,每遍历一个节点,如果发现其flag为false,则将其置为true,如果发现其为true,则说明该节点已经遍历过了,那第一次出现访问到flag为ture的节点便是环开始的节点。
实现代码:
我们这里采用第一种方法,我们在程序中构建好如下循环链表:
完整代码如下:
/*********************************
题目描述:
求一个有环的单链表中环开始处的节点
Date:2014-03-26
**********************************/
typedef int ElemType;typedef struct Node
{ElemType data;struct Node *next;
}Node,*pNode;#include<stdio.h>
#include<stdlib.h>/*
定义一个速度为2的快指针,一个速度为1的慢指针,
如果链表中有环,则返回两个指针相遇的节点,
如果没有链表中没有环,则返回NULL。
*/
pNode WetherCircle(pNode pHead)
{if(!pHead)return NULL;pNode p1 = pHead;pNode p2 = pHead;//直到二者相遇,退出循环while((p1 && p2 && p1!=p2) || (p1==p2 && p1==pHead && p2==pHead)){p1 = p1->next;p2 = p2->next->next;}if(p1 == p2)return p1;elsereturn NULL;
}/*
计算环中的节点个数
*/
int CircleLen(pNode pHead)
{pNode p = WetherCircle(pHead);if(!p)return 0;int count = 1;//固定一个指针,另一个指针在环中移动pNode p1 = p->next;while(p1 != p){count++;p1 = p1->next;}return count;
}/*
求环开始的节点
*/
pNode CircleBegin(pNode pHead)
{int len = CircleLen(pHead);if(len < 1)return NULL;pNode p1 = pHead;pNode p2 = pHead;int i;//第一个指针先移动len个节点for(i=0;i<len;i++)p1 = p1->next;//而后一起移动while(p1 != p2){p1 = p1->next;p2 = p2->next;}return p1;
}/*
建立如下所示的带环的单链表
1->2->3->4->5->6->7->4
即环的入口节点为date域为4的节点
*/
pNode create_CircleList()
{pNode pHead = (pNode)malloc(sizeof(Node));if(!pHead){printf("malloc faild!\n");exit(-1);}pHead->data = 1;pNode r = pHead;int i;for(i=0;i<6;i++){pNode pNew = (pNode)malloc(sizeof(Node));if(!pNew){printf("malloc faild!\n");exit(-1);}pNew->data = i + 2;r->next = pNew;r = pNew;}//将最后一节点的next指向第四个节点,形成环r->next = pHead->next->next->next;return pHead;
}int main()
{pNode pHead = create_CircleList();pNode p = CircleBegin(pHead);printf("The date in the beginNode of the Circle is:%d\n",p->data);return 0;
}
测试结果:
注:代码开源到我的Github:https://github.com/mmc-maodun/CareerCup
【CareerCup】 Linked Lists—Q2.5相关推荐
- 【leetcode】Linked List Cycle I II
Given a linked list, determine if it has a cycle in it. Can you solve it without using extra space? ...
- 【leetcode】Intersection of Two Linked Lists
Write a program to find the node at which the intersection of two singly linked lists begins. For ex ...
- 【LeetCode从零单排】No.160 Intersection of Two Linked Lists
题目 Write a program to find the node at which the intersection of two singly linked lists begins. For ...
- 114. Flatten Binary Tree to Linked List【Medium】【将给定的二叉树转化为“只有右孩子节点”的链表(树)】...
Given a binary tree, flatten it to a linked list in-place. For example, given the following tree: 1/ ...
- 【TensorRT】TensorRT was linked against cudnn 8.6.0 but loaded cudnn 8.3.2
[TensorRT]TensorRT was linked against cudnn 8.6.0 but loaded cudnn 8.3.2 1 电脑环境 2 问题描述 3 直接原因 4 解决办法 ...
- 【LeetCode】【数组归并】Merge k Sorted Lists
描述 Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity ...
- 【LeetCode】深搜DFS(共85题)
[98]Validate Binary Search Tree [99]Recover Binary Search Tree [100]Same Tree [101]Symmetric Tree [1 ...
- C#LeetCode刷题之#160-相交链表(Intersection of Two Linked Lists)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3824 访问. 编写一个程序,找到两个单链表相交的起始节点. 例如 ...
- 【缓存】Redis入门
redis命令 命令行链接redis redis-cli -h localhost -p 6478 -a password keys * 可以查看系统中所有的key值,在开发环境非常有用的命令 se ...
最新文章
- C - Catch That Cow(BFS)
- python 多级菜单_python多级菜单
- 磁头号和起始扇区的计算方法------软盘结构
- delphi的接口support_学习到的关于Delphi的接口
- python把英语句子成分字母_句子成分的表达字母
- 重返数学史的黄金时代,由数学推动诞生的人工智能,一部人类智慧形成的历史...
- c 语言比较三个字符串,C语言字符篇(三)字符串比较函数
- Linux内存管理:转换后备缓冲区(TLB)原理
- 35张动图:关于机房空调水冷系统和风冷系统
- 蓝星微商城源码+搭建教程源码
- hyper-v与Docker for windows和VMBox的冲突
- 计算机英语朗读音频,新课标小学英语阅读精选(MP3+中英字幕) 第72期:电脑
- 如何让你的Linux程序程序后台运行
- Google搜索从入门到精通
- 【开源WebGIS】07-Openlayers+Vue 测量功能-02
- 自定义Dialog 实现 仿网易云音乐的隐私条款声明弹框
- 2021-08-17 WPF控件专题 Canvas 控件详解
- 使用Ultra Libraian生成Altium Designer元件库
- oracle中lt;gt;是什么意思,c++中vectorlt;intgt;和vectorlt;int*gt;的用法区别
- 谷歌电子市场学习笔记第三天