算法:寻找两个单项链表的交点

10 篇文章 0 订阅

问题:寻找两个单项链表的交点。

一、输入输出。

输入:两个带空头结点的单向链表
输出:如果有相交的节点,输出节点值;如果没有,打印“没有找到相交节点”。

= =。好吧回头看了一下好像这个方法是错的。。。。。。

二、解题原理

  这题原理很简单,首先是遍历两个链表,获取它们的长度;然后求出它们的长度差(difference),让长的一个链表先前进difference的距离,也就是说此时两个链表剩下的元素值个数相等。接着两个链表都一步一步前进,如果发现某处有相同节点,则这个就是相交节点,反之两个节点分别前进到末端,返回Null。

三、代码实现(JAVA)

1.首先这是一个定义的节点。

class Node<T>{
    public Node next;
    public T data;

    public Node(){
        data = null;
        next = null;
    }

    public Node(T data, Node<T> next){
        this.data = data;
        this.next = next;
    }
}

2.然后这里是我们主要的查找算法。

    //查找两个单向链表的相交节点
    public static Node findTheCrossNode(Node lhs, Node rhs){
        int len_lhs = 0;
        int len_rhs = 0;
        Node tlhs = lhs;
        Node trhs = rhs;

        //计算链表一长度
        while (tlhs.next != null){
            len_lhs++;
            tlhs = tlhs.next;
        }

        //计算链表二长度
        while (trhs.next != null){
            len_rhs++;
            trhs = trhs.next;
        }

        //计算两个链表的长度差
        int difference = Math.abs(len_lhs - len_rhs);

        //先让长的一个链表走步长为difference的距离
        //然后开始两个链表同步向前,如果有相交节点则会找到相同节点
        //否则两个链表都到最后null
        if(len_lhs > len_rhs){

            for (int i = 0; i < difference; i++)
                lhs = lhs.next;
        }
        else {
            for (int i = 0; i < difference; i++)
                rhs = rhs.next;
        }

        while(lhs != rhs){
            System.out.println("node1 = " + lhs.data + " node2 = " + rhs.data);
            lhs = lhs.next;
            rhs = rhs.next;
        }

        return lhs;
    }

3.然后通过Main函数进行了测试,验证成功哈哈哈哈哈哈哈。在例子特地设置了相交节点值为2。

public static void main(String[] args) {
        //两个单项链表为带空头结点的链表
        Node<Integer> list1 = new Node<>(-1, null);
        Node<Integer> list2 = new Node<>(-1, null);

        Node cross = null;
        Node lastNode = list1;
        //构建链表一, 0->1->2->3->4
        for (int i = 0; i < 5; i++){
            lastNode.next = new Node<>(i, null);
            if (i == 2) //相交节点为4
                cross = lastNode.next;
            lastNode = lastNode.next;
        }

        //构建链表二, 10->9->8->2->3->4
        lastNode = list2;
        for (int i = 10; i > 7; i--){
            lastNode.next = new Node<>(i, null);
            lastNode = lastNode.next;
        }
        lastNode.next = cross;

        cross = findTheCrossNode(list1, list2);
        if (cross != null)
            System.out.println("相交节点值为: " + cross.data);
        else
            System.out.println("没有相交节点");
    }

4.输出结果如下

node1 = -1 node2 = 10
node1 = 0 node2 = 9
node1 = 1 node2 = 8
相交节点值为: 2

扩展问题

问题:如何判断一个单链表有环?
提示:用两个指针,一个每次递增一步,另一个每次递增两步,如果有环两个必重合,反之亦然。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值