单链表——判断两个单链表是否相交

本文介绍了一种判断两个单链表是否相交的方法,通过遍历两个链表找到各自的尾节点进行比较,若相同则说明两链表相交。此方法的时间复杂度为O(len1+len2),空间复杂度为O(1)。

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

package jxau.lyx.link;

/**
 * 
 * @author: liyixiang
 * @data:2014-10-2
 * @题目大意:
 * 		判断两个单链表是否相交   
 * @主要思路:
 * 		如果两个链表相交于某一节点,那么在这个相交节点之后的所有节点都是两个链表所共有的
 * 也就是说,如果两个链表相交,那么最后一个节点肯定是共有的。      
 * 		先遍历第一个链表,记住最后一个节点,然后遍历第二个链表, 到最后一个节点时和第
 * 一个链表的最后一个节点做比较,如果相同,则相交,否则不相交。
 * @时间复杂度:
 * 		时间复杂度为O(len1+len2)
 * @空间复杂度:
 * 		因为只需要一个额外指针保存最后一个节点地址 
 * 		空间复杂度为O(1) 
 */
public class IsIntersect {

	//结点
	private static class Node {           
		int val;           
		Node next;               
		
		public Node(int val) {               
			this.val = val;          
		}       
	}
	
	
	public boolean isIntersect(Node head1,Node head2){
		
		if (head1 == null || head2 == null) {              
			 return false;     
		 }       
		
	 	Node tail1 = head1;     
	 	
	 	// 找到链表1的最后一个节点      
	 	while (tail1.next != null) {
	 		tail1 = tail1.next;     
	 	}   
	 	
	 	Node tail2 = head2; 
	 	
	 	// 找到链表2的最后一个节点      
	 	while (tail2.next != null) {       
	 		tail2 = tail2.next;   
	 	}     
	 	return tail1 == tail2; 
	}
		  
}


转载于:https://my.oschina.net/liyixiangBlog/blog/323866

### 关于C语言单链表练习题全集 #### 查找中间节点 对于查找单链表中的中间节点,可以通过快慢指针的方法实现。具体来说,在遍历过程中设置两个指针`f`和`s`均指向头部。每次迭代中,快指针前进两步而慢指针仅移动一步。当快指针到达链表末端时,慢指针正好位于中间位置[^1]。 ```c struct ListNode* middleNode(struct ListNode* head){ struct ListNode* f = head, *s = head; while (f && f->next) { s = s->next; f = f->next->next; } return s; } ``` #### 判断是否存在环形结构 为了检测链表内部是否形成闭环,同样采用双指针策略——即让一个指针一次跳跃两次(快速),另一个则逐个访问相邻元素(缓慢)。只要存在循环路径,最终这两者会在某处交汇;反之,若无环路,则较快的那个会率先抵达终点[^2]。 ```c bool hasCycle(struct ListNode *head) { struct ListNode* slow = head; struct ListNode* fast = head; while (fast && fast->next) { slow = slow->next; fast = fast->next->next; if (slow == fast) { return true; } } return false; } ``` #### 定位环入口点 进一步扩展上述方法来定位环的具体起始位置:一旦发现快慢指针相遇之后,保持其中一个不动,另设一个新的指针从列表开头出发并前者同步推进直至二者再次碰面之处即是所求之环首[^3]。 ```c struct ListNode *detectCycle(struct ListNode *head) { struct ListNode *slow = head, *fast = head; do { if (!fast || !fast->next) return NULL; slow = slow->next; fast = fast->next->next; } while (slow != fast); // Once cycle detected, find the entrance of the loop. struct ListNode *ptr1 = head, *ptr2 = slow; while (ptr1 != ptr2) { ptr1 = ptr1->next; ptr2 = ptr2->next; } return ptr1; // or ptr2 since they are equal now } ``` #### 处理回文链表特殊情况 针对某些特定场景下的优化处理也值得注意,比如在验证链表是否构成回文字串的过程中可能会遇到相交情况。此时虽然不必切断连接关系但仍需谨慎操作以免破坏原有数据完整性[^4]。 ```c // 假设已经实现了获取中间节点函数middleNode() void reverseList(struct ListNode **headRef) {/* ... */} bool isPalindrome(struct ListNode *head) { if (!head || !(head->next)) return true; struct ListNode *mid = middleNode(head); // 获取中间节点 struct ListNode *secondHalfStart = mid->next; mid->next = NULL; // 断开前后半部分 secondHalfStart = reverseList(&secondHalfStart); struct ListNode *p1 = head, *p2 = secondHalfStart; bool result = true; while (result && p2 != NULL) { if (p1->val != p2->val) result = false; p1 = p1->next; p2 = p2->next; } // 恢复原状并返回结果... /* ... */ return result; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值