1.给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。
public class Solution {
public ListNode detectCycle(ListNode head) {
Set<ListNode> set = new HashSet<>();
ListNode h1 = head;
while(h1!=null){
if(set.contains(h1)){
return h1;
}else{
set.add(h1);
h1=h1.next;
}
}
return null;
}
}
2.求不带环相交链表起始节点
public class Solution {
public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
ListNode h1 = headB;
ListNode h2 = headA;
while(h1!=h2){
h1=h1==null?headA:h1.next;
h2=h2==null?headB:h2.next;
}
return h1;
}
}
3.求带环单链表的环的长度
快慢指针从第一次相遇开始进行累加直到第二次相遇跳出循环
public static int lengthCircle(ListNode head){
if(head==null)
return -1;
ListNode fast = head;
ListNode low = head;
int count= 0;
int sum = 2;
boolean flag = false;
while(fast!=null&&fast.next!=null){
slow = slow.next;
fast = fast.next.next;
if(slow==fast){
flag=true;
sum--;
}
if(sum==0)
break;
if(flag){
count++;
}
}
return count;
}
4.判断两个链表(可能带环)是否相交
分析:
两个都不带环:可能会相交
其中一个带环:不可能相交
两个都带环:可能相交,两种情况(环外相交,环内相交)
public boolean IsListCrossWithCircle(ListNode list1, ListNode list2){
if (list1==null && list1==null){
return false;
}
ListNode Node1 = NULL, Node2 = NULL;
//先各自判断两个链表是否带环(带环返回相遇点,否则返回空)
Node1 = detectCircle(list1);
Node2 = detectCircle(list2);
//两个链表都不带环
if (Node1==null && Node2==null)
{
//只要证明最后一个节点是相同的
ListNode Tail1 = list1;
ListNode Tail2 = list2;
if (Tail1==NULL || Tail2==NULL){
return false;
}
while (Tail1.next){
Tail1 = Tail1.next;
}
while (pTail2.next){
Tail2 = Tail2.next;
}
if (pTail1 == pTail2)
{
return true;
}
}
//两个链表均带环
else if (Node1 && Node2){
if(Node1==Node2)//相遇点相同,说明环外相交
return true;
ListNode cur = Node1;
while (cur.next != Node1){
if (cur == Node2){
return true;
}
cur = cur.next;
}
}
return false;
}