判断两条链表是否相交(公共部分)并找出相交处

Problem:
  两个单链表相交的一系列问题
  【题目】 在本题中,单链表可能有环,也可能无环。给定两个
    单链表的头节点 head1和head2,这两个链表可能相交,也可能
    不相交。请实现一个函数, 如果两个链表相交,请返回相交的
    第一个节点;如果不相交,返回null 即可。
  要求:

    如果链表1 的长度为N,链表2的长度为M,时间复杂度请达到 O(N + M),额外
    空间复杂度请达到O(1)

Solution:
  对于判断单链表是否有环,则使用快慢指针即可知道,两指针相交,则有环
  对于判断双链表是否相交,则判断遍历链表的最后指针的地址是否相同,相同则有公共部分
  然后在从头遍历,长的链表先遍历长的部分,然后一起遍历,当指针相同时,则为相交的部位。

Code:

  

  1 #include <iostream>
  2
  3 using namespace std;
  4
  5 struct Node
  6 {
  7     int val;
  8     Node* next;
  9     Node(int a = 0) :val(a), next(NULL) {}
 10 };
 11
 12 void FindNode(Node* head1, Node* head2)
 13 {
 14     if (head1->next == NULL || head2->next == NULL)
 15         return;
 16     Node *p1, *p2;
 17     p1 = head1->next;
 18     p2 = head2->next;
 19     int size1, size2;//计算链表长度
 20     size1 = size2 = 1;
 21     while (p1->next || p2->next)
 22     {
 23         if (p1->next)
 24         {
 25             p1 = p1->next;
 26             size1++;
 27         }
 28         if (p2->next)
 29         {
 30             p2 = p2->next;
 31             size2++;
 32         }
 33     }
 34     if (p1 != p2)
 35     {
 36         cout << "List1 and List2 have no commmon part!" << endl;
 37         return;
 38     }
 39     cout << "List1 and List2 have commmon part!" << endl;
 40     //重新遍历,找到交点
 41     p1 = head1->next;
 42     p2 = head2->next;
 43     for (int i = 0; i<(size1>size2 ? size1 - size2 : size2 - size1); ++i)//长的先遍历
 44     {
 45         if (size1 > size2)
 46             p1 = p1->next;
 47         else
 48             p2 = p2->next;
 49     }
 50     while (p1 != p2)
 51     {
 52         p1 = p1->next;
 53         p2 = p2->next;
 54     }
 55     cout << "相交部位为:addr:" << p1 << "  val:" << p1->val << endl;
 56
 57 }
 58
 59 void Test()
 60 {
 61     int a[] = { 1,2,3,4,5,6 };
 62     int b[] = { 4,5,6 };
 63     int c[] = { 7,8,9,10 };
 64     Node* head1 = new Node(-1);
 65     Node* head2 = new Node(-1);
 66     Node* p1 = head1;
 67     Node* p2 = head2;
 68
 69     for (auto n : a)
 70     {
 71         Node* q = new Node(n);
 72         p1->next = q;
 73         p1 = q;
 74     }
 75     p1->next = NULL;
 76     for (auto n : b)
 77     {
 78         Node* q = new Node(n);
 79         p2->next = q;
 80         p2 = q;
 81     }
 82     p2->next = NULL;
 83
 84     cout << "相交之前判断:" << endl;
 85     FindNode(head1, head2);
 86     cout << "***********************" << endl;
 87     for (auto n : c)
 88     {
 89         Node* q = new Node(n);
 90         p1->next = q;
 91         p1 = q;
 92         p2->next = q;
 93         p2 = q;
 94     }
 95     p1->next = NULL;
 96     p2->next = NULL;
 97
 98     cout << "相交之后判断:" << endl;
 99     FindNode(head1, head2);
100     cout << "***********************" << endl;
101 }

原文地址:https://www.cnblogs.com/zzw1024/p/10989469.html

时间: 2024-10-13 21:46:54

判断两条链表是否相交(公共部分)并找出相交处的相关文章

poj1039——计算几何 求直线与线段交点,判断两条直线是否相交

poj1039——计算几何  求直线与线段交点,判断两条直线是否相交 Pipe Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 9439   Accepted: 2854 Description The GX Light Pipeline Company started to prepare bent pipes for the new transgalactic light pipeline. During the de

编程之美---判断两个链表是否相交

首先,判断一个链表是否有环? 对于这个问题:可以用两个指针,刚开始都指向头节点,然后一个指针每次向后移一步,另一个指针每次向后移两步,如果最后移两步的指针为空时,说明无环,如果最后两个指针相等,说明有环.如果把第一指针看成静止,则相当于第二个每次走一步,所以在那个环上时,是一定能相遇的. 如何找到这个链表环的入口? 当这两个指针相遇后,把第一个指针移向头,两个指针每次都只移一步,再次相等时,就是环的入口.证明:设环上相遇位置为距离环入口处P,入口处前有M个节点,,环肾功能有N个节点,从入口处开始

数据结构和算法设计专题之---判断两个链表是否相交并找出交点

题目: 一个比较经典的问题,判断两个链表是否相交,如果相交找出他们的交点. 首先来看一下如何判断两个链表是否存在相交的节点: 思路: 1.碰到这个问题,第一印象是采用hash来判断,将两个链表的节点进行hash,然后判断出节点,这种想法当然是可以的. 2.当然采用暴力的方法也是可以的,遍历两个链表,在遍历的过程中进行比较,看节点是否相同. 3.第三种思路是比较奇特的,在编程之美上看到的.先遍历第一个链表到他的尾部,然后将尾部的next指针指向第二个链表(尾部指针的next本来指向的是null).

【IT公司100题-7】-判断两个链表是否相交

问题:有一个单链表,其中可能有一个环,也就是某个节点的next指向的是链表中在它之前的节点,这样在链表的尾部形成一环.1.如何判断一个链表是不是这类链表? 问题扩展:1.如果链表可能有环呢?2.如果需要求出两个链表相交的第一个节点呢? 分析: 在无环的情况下,如果两个链表有结点相同,那么它们下一结点也相同,如此可推出尾结点也相同. 那么只要判断两链表的尾结点是否相同.(O(len1+len2)) 1 struct Node { 2 int data; 3 int Node *next; 4 };

判断两个链表是否相交

1 假设两个链表都没有环 解题思路 a. 直接循环判断第一个链表的每个节点是否在第二个链表中.但,这种方法的时间复杂度为O(Length(h1) * Length(h2)).显然,我们得找到一种更为有效的方法,至少不能是O(N^2)的复杂度. b. 针对第一个链表直接构造hash表,然后查询hash表,判断第二个链表的每个节点是否在hash表出现,如果所有的第二个链表的节点都能在hash表中找到,即说明第二个链表与第一个链表有相同的节点.时间复杂度为为线性:O(Length(h1) + Leng

链表相交问题:判断两个链表是否相交,若相交求交点

默认为不带环链表,若带环则延伸为判断链表是否带环,若带环,求入口点 看看两个链表相交到底是怎么回事吧,有这样的的几个事实:(假设链表中不存在环) (1)一旦两个链表相交,那么两个链表中的节点一定有相同地址. (2)一旦两个链表相交,那么两个链表从相交节点开始到尾节点一定都是相同的节点. #include<iostream> #include<assert.h> using namespace std; template<class T> struct LinkNode

数字之魅:判断两个链表是否相交

题目:给出两个链表的头指针,比如head1和head2,判断这两个链表是否相交.这里为了化简,我们假设两个链表均不带环. 方案一:蛮力法.一般我们都能想到的,就是从head1开始,逐个与head2中的每个结点的地址比较,看是否相等,如果不等,则head1移动到下一个结点,继续和head2中的每一个结点的地址比较:如果找到相等,则这两个链表相交:直到head1==NULL,则不相交.注意为了避免存在相同的元素,我们采取比较地址的方法,而不是比较元素,在判断链表里是否有环的时候,也是采用比较地址的方

判断两个链表是否相交(带环)

解决方案: 1.找出链表1的环入口节点a1,链表2的环入口节点a2; 2.如果a1=a2; 说明两个链表可能在入环之前或者入环第一个节点相交:将a1,a2作为两个链表的最后一个节点,转化为不带环的链表相交:其实在这种情况下已经说明两个链表已经相交了. 3.如果a1!=a2;以a1为基准节点进行while循环,如果在循环中找到跟a2相同的节点,说明两个链表相交:如果没找到,说明不相交. #如果1个链表不带环,1个链表带环:则两个链表必不相交:

判断两个链表是否相交;查找两个链表的第一个公共节点

问题一:(引用编程之美)如果两个链表相交,则尾节点一定是公共的 问题二: 1 int listLength(node* list){ 2 int length=0; 3 while(list!=NULL){ 4 length++; 5 list=list->next; 6 } 7 return length; 8 } 9 // 10 node* firstComNode(node* list1,node* list2){ 11 int n1=listLength(list1); 12 int n