链表----两个单链表相交的一系列问题

博客介绍了链表相关的关键点及代码。判断链表是否有环可利用快慢指针,若有环快慢指针会相交,第一次相遇后快指针回起点并一步一步走,两指针会在入环节点再次相遇。还提及两个无环链表相交呈Y型,两个有环链表相交则共享一个环,分入环节点相同和不同两种情况。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 关键点:

1、判断链表是否有环

  • 利用快慢指针,若链表有环,快慢指针一定会相交
  • 快慢指针第一次相遇后,快指针回到头节点,变为一次走一步,两指针再次在入环节点处相遇

2、两个无环链表相交

  • 若相交,两链表是Y型结构

3、两个有环链表相交:若相交,两个链表一定是共享一个环

  1. 入环节点相同:先相交再共享环
  2. 入环节点不同,两个链表分别有一个入环节点

 代码

//一、判断链表是否有环,无环返回null  有环返回入环节点
	public static Node getLoopNode(Node head) {
		if(head == null || head.next == null || head.next.next == null) {
			return null;
		}
		//利用快慢指针
		Node fast = head.next.next;
		Node slow = head.next;
		//如果有环,快慢指针一定会相遇
		while(fast != slow) {
			//如果快指针在遍历的时候遇到null 说明一定无环
			if(fast.next == null || fast.next.next == null) {
				return null;
			}
			fast = fast.next.next;
			slow = slow.next;
		}
		//快慢指针相遇时,快指针回到头节点;
		fast = head;
		//快指针改一次走一步,快慢指针在入环节点处相遇
		while(fast != slow) {
			fast = fast.next;
			slow = slow.next;
		}
		return fast;
	}
	//二、判断链表是否相交 如果相交返回相交节点;不想交,返回null
	public static Node getIntersect(Node head1,Node head2) {
		if(head1 == null || head2 == null) return null;
		Node loop1 = getLoopNode(head1);
		Node loop2 = getLoopNode(head2);
		
		//1、两无环链表相交  Y型结构
		
		if(loop1 == null && loop2 == null) {
			return noLoop(head1,head2);
		}
		
		//2、一个有环一个无环   一定不相交!!
		else if(loop1 == null || loop2 == null) {
			return null;
		}
		//3、两个有环链表相交
		else {
			return bothLoop(head1,head2,loop1,loop2);
		}
	}
	//两无环链表相交  
	public static Node noLoop(Node head1,Node head2) {
		//两个指针分别遍历head1 和 head2 返回相交节点 或者null
		Node p1 = head1;
		Node p2 = head2;
		while(p1 != p2) {
			p1 = p1 == null ? head2 : p1.next;
			p2 = p2 == null ? head1 : p2.next;
		}
		return p1;
	}
	//两个有环链表相交
	//两有环链表相交一定是共享一个环  分两种情况
    public static Node bothLoop(Node head1,Node head2,Node loop1,Node loop2) {
		//1、先相交再共享环,相当于两无环链表相交问题
    	if(loop1 == loop2) {
    		Node p1 = head1;
    		Node p2 = head2;
    		while(p1 != p2) {
    			p1 = p1 == loop1 ? head2 : p1.next;
    			p2 = p2 == loop2 ? head1 : p2.next;
    		}
    		return p1;
    	}
    	//2、 \____/
    	//   |__|
    	else {

    		while(loop1.next != loop1) {
    			//如果相交一定会相遇
    			if(loop1 == loop2) {
    				return loop2;
    			}
    			loop1 = loop1.next;
    		}
    		return null;	
    	}
	}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值