链表中环的入口结点(链表)
来源:互联网 发布:软件二次开发难吗 编辑:程序博客网 时间:2024/06/05 16:33
题目描述:一个链表中包含环,请找出该链表的环的入口结点。
public class ListNode { int val; ListNode next = null; ListNode(int val) { this.val = val; }}
思路一:
1. 找环中相汇点。分别用p1,p2指向链表头部,p1每次走一步,p2每次走二步,直到p1==p2找到在环中的相汇点。
2. 找环的入口。
接上步,当p1==p2时,p2所经过节点数为2x,p1所经过节点数为x,设环中有n个节点,p2比p1多走一圈,有2x=n+x,n=x;
可以看出p1实际走了一个环的步数,再让p2指向链表头部,p1位置不变,p1,p2每次走一步,直到p1==p2,此时p1指向环的入口。
public class Solution { public ListNode EntryNodeOfLoop(ListNode pHead) { if (pHead == null) return null; ListNode p1 = pHead; ListNode p2 = pHead; while (p2 != null && p2.next != null) { p1 = p1.next; p2 = p2.next.next; if (p1 == p2) { p2 = pHead; while (p1 != p2) { p1 = p1.next; p2 = p2.next; } if (p1 == p2) return p1; } } return null; }}
思路二:
如果链表中环 有n个结点,指针P1在链表上向前移动n步,然后两个指针以相同的速度向前移动。
当第二个指针P2指向环的入口结点时,第一个指针P1已经围绕着环走了一圈又回到了入口结点。 所以首先要得到环中结点的数目。
找到一快一满指针相遇处的节点,相遇的节点一定是在环中。
public class Solution { public ListNode EntryNodeOfLoop(ListNode pHead) { if (pHead == null) return null; ListNode meetingNode = MeetingNode(pHead); if (meetingNode == null) return null; ListNode tmpNode = meetingNode; int loopCount = 1; while (tmpNode.next != meetingNode) { tmpNode = tmpNode.next; ++loopCount; } ListNode p1 = pHead; ListNode p2 = pHead; for (int i = 1; i <= loopCount; i++) p1 = p1.next; while (p1 != p2) { p1 = p1.next; p2 = p2.next; } return p1; } private ListNode MeetingNode(ListNode pHead) { if (pHead == null) return null; ListNode slow = pHead.next; if (slow == null) return null; ListNode fast = slow.next; while (slow != null && fast != null) { if (slow == fast) return fast; slow = slow.next; fast = fast.next; if (slow != fast) fast = fast.next; } return null; }}
思路三:
时间复杂度为O(n),两个指针,一个在前面,另一个紧邻着这个指针,在后面。 两个指针同时向前移动,每移动一次,前面的指针的next指向NULL。访问过的节点都断开,最后到达的那个节点一定是尾节点的下一个, 也就是循环的第一个。 这时候已经是第二次访问循环的第一节点了,第一次访问的时候我们已经让它指向了NULL, 所以到这结束。
这样会破坏原始数据。
public class Solution { public ListNode EntryNodeOfLoop(ListNode pHead) { if (pHead == null || pHead.next == null) return null; ListNode p1 = pHead; ListNode p2 = pHead.next; while (p2 != null) { p1.next = null; p1 = p2; p2 = p2.next; } return p1; }}
思路四:
import java.util.HashSet;public class Solution { public ListNode EntryNodeOfLoop(ListNode pHead) { if (pHead == null) return null; HashSet<ListNode> set = new HashSet<>(); while (pHead != null) { if (set.add(pHead)) pHead = pHead.next; else return pHead; } return null; }}
阅读全文
0 0
- 链表中环的入口结点(链表)
- 链表:链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 链表中环的入口结点
- 比特币源码解读四
- Fragment 表示 Activity 中的行为或用户界面部分
- webView 收起和展开
- 安卓webview和JS交互,使用连接桥JsBridge进行连
- R语言——1初学
- 链表中环的入口结点(链表)
- 操作系统 — fork()函数的使用与底层原理
- 国家语言代码
- 唯快不破:高性能网络服务器1--accept建立连接
- 不得不知的5种数据安全预测
- LeetCode--First Unique Character in a String(字符串中第一个不重复的字母)Python
- Java面试常被问到的题目+解答
- wifi传文件
- 数据库设计