2-12寻找相交链表的相交节点

题目描述

  • 两个单链表,它们可能相交也可能不相交,传入两个头节点,如果相交返回第一个相交节点,如果不相交返回null。
  • 如果两个链表相交,从相交节点往后的部分是两个链表共享的。

解题方法1

  • 最简单的方法可以使用哈希表,依次遍历两个链表将节点指针存放到哈希表,那么哈希表中第一个重复的节点就是相交节点。
  • 但是空间复杂度为n。
public class Test {
    public static void main(String[] args) throws Exception {
         int[] arr1 = {1,2,3,4,5,6,7,8,9};
         int[] arr2 = {10,20,30};
         Node head1 = create1(arr1);
         Node head2 = create1(arr1);
         head2.next.next.next.next = head1.next.next.next.next; //链表2的尾节点指向链表1的节点4
         Node node = fun(head1,head2);
         System.out.println(node);
    }
    //获取两个链表第一个相交节点
    public static Node fun(Node head1,Node head2){
        HashSet<Node> set = new HashSet();
        for(Node p=head1.next;p!=null;p=p.next){
            set.add(p);
        }
        for(Node p=head2.next;p!=null;p=p.next){
            if(set.contains(p)){
                return p;
            }
            set.add(p);
        }
        return null;
    }
    //创建一个无环单链表
    public static Node create1(int[] arr){
        Node head = new Node(0); //头节点
        Node newnode = null; //指向新节点
        Node lastnode = head; //指向链表尾节点
        for(int a:arr){
            newnode = new Node(a); //创建新节点
            newnode.next = lastnode.next; //尾插核心操作
            lastnode.next = newnode;
            lastnode = newnode; //迭代指针
        }
        return head;
    }
}
class Node{
    int val;
    Node next;
    Node(int val){
        this.val = val;
    }
}

解题方法2

  • 我们可以先求出两个链表的长度,再重新遍历链表找相交节点。
  • 如果链表1比链表2长a个节点,我们可以定义两个指针,让链表1指针先走a步,然后两个链表指针一起走,如果两个指针出现指向相同节点的情况就把该节点返回,如果两个指针走到结尾都没有相遇说明两个链表不相交。
public class Test {
    public static void main(String[] args) throws Exception {
         int[] arr1 = {1,2,3,4,5,6,7,8,9};
         int[] arr2 = {10,20,30};
         Node head1 = create1(arr1);
         Node head2 = create1(arr2);
         head2.next.next.next.next = head1.next.next.next.next; //链表2的尾节点指向链表1的节点4
         Node node = fun(head1,head2);
         System.out.println(node.val);
    }
    //获取两个链表第一个相交节点
    public static Node fun(Node head1,Node head2){
        int len1 = 0;
        int len2 = 0;
        for(Node p=head1.next;p!=null;p=p.next){
            len1++;
        }
        for(Node p=head2.next;p!=null;p=p.next){
            len2++;
        }
        int num = Math.abs(len1-len2); //求两个链表的差值
        Node shortp = len1>len2?head2.next:head1.next;//指向短链表
        Node longp = len1>len2?head1.next:head2.next; //指向长链表
        //长链表指针先走num步
        while(num>0){
            longp = longp.next;
            num--;
        }
        System.out.println(shortp.val + "--" + longp.val);
        //然后两个指针一起走
        while (shortp!=null && longp!=null){

            if(shortp==longp){
                return shortp;
            }
            shortp = shortp.next;
            longp = longp.next;
        }
        return null;
    }
    //创建一个无环单链表
    public static Node create1(int[] arr){
        Node head = new Node(0); //头节点
        Node newnode = null; //指向新节点
        Node lastnode = head; //指向链表尾节点
        for(int a:arr){
            newnode = new Node(a); //创建新节点
            newnode.next = lastnode.next; //尾插核心操作
            lastnode.next = newnode;
            lastnode = newnode; //迭代指针
        }
        return head;
    }
}
class Node{
    int val;
    Node next;
    Node(int val){
        this.val = val;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章