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;
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章