链表带环或不带环的几个经典问题

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;
}
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值