(劍指offer)兩個單向鏈表,找出它們的第一個公共結點

題目:輸入兩個單向鏈表,找出它們的第一個公共結點
如:給定鏈表1:6–>1–>2–>4–>3–>2–>5–>2–>6
    鏈表2:2–>1–>8–>3–>2–>5–>2–>6


算法思路:
  首先第一次遍歷兩個鏈表,分別得到它們的長度爲m和n,判斷鏈表長度m和n的大小,第二次遍歷時,先在較長的一個鏈表上走(m-n或n-m)步,再同時在兩個鏈表上遍歷,直到找到它們第一個相同的結點3;
  
時間複雜度爲: O(m+n)


代碼如下:

public class Node {
    public int value;
    public Node next;

    public Node() {}

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

    public static void main(String[] args) {
        int[] arr_1 = { 6, 1, 2, 4, 3, 2, 5, 2, 6 };
        int[] arr_2 = { 2, 1, 8, 3, 2, 5, 2, 6 };
        Node link_1 = generateLink(arr_1);
        Node link_2 = generateLink(arr_2);
        print(link_1.next);
        print(link_2.next);
        System.out.println(findFirstSameNode(link_1, link_2).value);
    }

    /**
     * 計算兩個單鏈表的第一個公共結點,找到返回結點,否則返回null
     * @param head_1
     * @param head_2
     * @return
     */
    public static Node findFirstSameNode(Node head_1, Node head_2) {
        if (head_1 == null || head_2 == null) {
            return null;
        }
        int lengthOfHead_1 = calculateLength(head_1);
        int lengthOfHead_2 = calculateLength(head_2);
        if (lengthOfHead_1 > lengthOfHead_2) { // 判斷一下兩個鏈表的長度,此時鏈表head_1較長
            for (int i = 0; i < lengthOfHead_1 - lengthOfHead_2; i++) {
                head_1 = head_1.next;
            }
            while (head_2 != null) {
                if (head_1.value == head_2.value)
                    return head_1;
                head_1 = head_1.next;
                head_2 = head_2.next;
            }
        } else { // 此時鏈表head_2較長
            for (int i = 0; i < lengthOfHead_2 - lengthOfHead_1; i++) {
                head_2 = head_2.next;
            }
            while (head_1 != null) {
                if (head_1.value == head_2.value)
                    return head_1;
                head_1 = head_1.next;
                head_2 = head_2.next;
            }
        }
        return null;
    }

    /**
     * 計算鏈表的長度
     * @param head
     * @return 返回鏈表的長度
     */
    public static int calculateLength(Node head) {
        Node temp = head.next;
        int len = 0;
        while (temp != null) {
            len++;
            temp = temp.next;
        }
        return len;
    }

    /**
     * 傳入數組參數構造單鏈表
     * @param arr 數組
     * @return 構造的單鏈表
     */
    public static Node generateLink(int[] arr) {
        Node head = new Node(); // 鏈表的頭結點
        Node pre = head;
        for (int i = 0; i < arr.length; i++) { // 遍歷數組構建鏈表
            Node node = new Node(arr[i]);
            pre.next = node; // 構造鏈表
            pre = node;
        }
        return head;
    }

    /**
     * 打印輸出鏈表的結點值
     * @param head 鏈表頭結點的下一個結點
     */
    public static void print(Node head) {
        while (head != null) {
            System.out.print(head.value + " ");
            head = head.next;
        }
        System.out.println();
    }
}

結果如下:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章