题目
给定两个可能有环的单链表,头节点head1和head2。 请实现一个函数,如果两个链表相交,请返回相交的第一个节点。如果不相交,返回null。
一、单链表相交的情况
两个无环单链表相交
这种方式可以用线性时间复杂度和常数级的空间时间复制度解决,考虑如上图的情况,可以的得出以下结论
两个无环单链表若相交,那么它们的最后一个结点一定是相等的。
根据这个原理我们,我们只需要遍历到两个链表的最后一个结点,判断其是否相等就能判断两个无环链表是否相交。但是,现在我们需要返回相交的第一个结点,只考虑上图的情况,我们可以用两个链表长度的差值来对齐两个链表,然后用两个指针找出第一个相同的结点,过程如下:
1)遍历两个链表记录长度 l1 与 l2 ,判断它们最后结点是否相等,不相等返回null,否则进入2
2)p = head1, q = head2, t = abs( l1 - l2 ),找出较长的链表,将 p 或者 q 移动 t 个单位
3)比较 p q 若相等则返回 p 或 q
代码如下:
/**
* 在无环的链表上找相交的第一个结点
* 1:若两个无环链表相交,则最后一个结点一定相同
* 2:若两个链表长度不相同,则较长的那个链表偏移两个链表长度之差的长度,然后用两个指针找相同结点
*
* @param head1 无环链表1
* @param head2 无环链表2
* @return
*/
public static MyList findCrossPointWithoutCycle(MyList head1, MyList head2) {
MyList p, q;
p = head1;
q = head2;
int l1 = 1, l2 = 1;
while (p.next != null) {
p = p.next;
l1++;
}
while (q.next != null) {
q = q.next;
l2++;
}
// 两个链表相交
if (q == p) {
p = head1;
q = head2;
int t = 0;
if (l1 > l2) {
t = l1 - l2;
for (int i = 0; i < t; i++) {
p = p.next;
}
} else if (l1 < l2) {
t = l2 - l1;
for (int i = 0; i < t; i++) {
q = q.next;
}
}
while (p != null && q!=null){
if (p == q){
return p;
}
p = p.next;
q = q.next;
}
}
return null;
}
两个有环的单链表相交,入口结点一致
这种情况,如果我们可以找到两个链表的入环结点,那么我们可以归结为判断两个无环单链表是否相交的问题。找到首个入环结点,的算法如果不用Hash表,则需要用到数学技巧,这里就不展开,假设我们已经实现了找到一个单链表的首个入环结点的算法,那么先拿到两个单链表的首个入环结点,然后调用上面的函数,就可以判断这一类情况。
两个有环的单链表相交,入口结点不一致
如上图所示的相交情况,我们如果找到了两个单链表的入环结点,调用第一类情况的函数,则会返回null,这时候就需要用两个链表的入环节点进行遍历,假设两个链表的入环节点分别为loop1和loop2,有如下伪代码:
p = loop1.next;
while(p != loop1){
if(p == loop2){
return p;
}
p = p.next;
}
return null;
这样就可以解决了第三类相交情况。
data = pd.read_csv( 'https://labfile.oss.aliyuncs.com/courses/1283/adult.data.csv') print(data.head())
该处使用的url网络请求的数据。
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。