链表算法(二):两个链表,判断是否相交成环,并找到两个链表相交的第一个节点

1. 定义单链表的数据结构类-Node

      //定义vlue
        public int value;
        //定义当前节点的下一个节点
        public Node next;

        public Node(int val) {
            this.value = val;
        }

2 测试Main函数

 public static void main(String[] args) {
        Node node = new Node(1);
        node.next = new Node(2);
        node.next.next = new Node(3);
        node.next.next.next = new Node(4);
        node.next.next.next.next = new Node(5);
        node.next.next.next.next.next = new Node(6);
        node.next.next.next.next.next.next = new Node(7);
//        node.next.next.next.next.next.next.next = node.next.next.next;

        Node node2 = new Node(11);
        node2.next = new Node(12);
        node2.next.next = new Node(13);
        node2.next.next.next = new Node(14);
        node2.next.next.next.next = new Node(15);
        node2.next.next.next.next.next = new Node(16);
//        node2.next.next.next.next.next.next = node.next.next.next.next.next.next;
//        node2.next.next.next.next.next.next = node2.next.next;
        node2.next.next.next.next.next.next =      node.next.next;


        Node restNode = getInstersectNode(node, node2);
        System.out.println(restNode.value);

    }

3. 查找两个链表是否有环,是否相交,并返回相交的第一个节点入口函数

    //查找两个链表是否有环,是否相交,并返回相交的第一个节点
    public static Node getInstersectNode(Node node1, Node node2) {

        Node loopNode1 = findLoop(node1);
        Node loopNode2 = findLoop(node2);

        if (loopNode1 != null && loopNode2 != null) {
            return bothLoopNode(node1, loopNode1, node2, loopNode2);
        }
        if (loopNode1 == null && loopNode2 == null) {
            return noLoopNode(node1, node2);
        }
        return null;
    }

4. 两个链表不成环,获取相交的节点函数

 public static Node noLoopNode(Node node1, Node node2) {
        if (node1 == null || node2 == null) {
            return null;
        }
        //定义两个变量
        Node cur1 = node1;
        Node cur2 = node2;
        int count = 0;
        //让cur1先迭代循环,并对count++
        while (cur1 != null) {
            count++;
            cur1 = cur1.next;

        }
        //让cur2迭代循环,并对count--
        while (cur2 != null) {
            cur2 = cur2.next;
            count--;
        }
        //cur1和cur2都走到了最后,判断二者是否相等,如果不相等说明二者没有相交
        if (cur1 != cur2) {
            return null;
        }
        //对cur1和cur2 重新 赋值,
        //cur1是长链表,反之短链表
        cur1 = count > 0 ? node1 : node2;
        cur2 = cur1 == node1 ? node2 : node1;
        count = Math.abs(count);
        //长链表先走
        while (count != 0) {
            cur1 = cur1.next;
            count--;
        }
        //cur1和cur2一起走
        //找到二者相交的第一个节点
        while (cur1 != cur2) {
            cur1 = cur1.next;
            cur2 = cur2.next;
        }
        return cur1;
    }

5. 两个链表都成环获取相交的第一个节点(两种情况)

 第一种:成环节点一样,说明相交节点在成环前面
 第二种:成环节点不一样,说明相交节点在环内
  /**
     * 两个链表都成环,判断是否相交
     * 如果相交返回第一个节点
     */
    public static Node bothLoopNode(Node node1, Node loopNode1, Node node2, Node loopNode2) {
        //两个链表都成环并且成环的节点都一样,说明二者是相交
        if (loopNode1 == loopNode2) {

            Node cur1 = node1;
            Node cur2 = node2;
            int count = 0;
            //计算到node1 头节点到成环节点的个数
            while (cur1 != loopNode1) {
                count++;
                cur1 = cur1.next;
            }
            //计算到node2 头节点到成环节点的个数
            while (cur2 != loopNode2) {
                count--;
                cur2 = cur2.next;
            }
            //重新制定cur1和cur2 ,cur1 为长链表
            cur1 = count > 0 ? node1 : node2;
            cur2 = cur1 == node1 ? node2 : node1;
            count = Math.abs(count);
            //长链表先走多出来的节点
            while (count != 0) {
                cur1 = cur1.next;
                count--;
            }
            //找到两个链表的相交点,相交的点一定一样,
            while (cur1 != cur2) {
                cur1 = cur1.next;
                cur2 = cur2.next;
            }
            return cur1;
        } else {
            Node cur1 = loopNode1.next;
            while (cur1 != loopNode1) {

                if (cur1 == loopNode2) {
                    return cur1;
                }
                cur1 = cur1.next;
            }
        }

        return null;

    }
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容