算法-单链表相交问题

题目

给定两个可能有环的单链表,头节点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提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值