找到两个链表的合并点

  假设两个单项链表在某个点相交后,成为一个单向链表。两个链表的表头节点是已知的,但是相交的节点未知。也就是说,他们相交之前各自的节点数是位置的,并且两个链表的节点数也可能不同。假设链表List1和链表List2在相交前的节点数分别为n何m,那么m可能等于或小于n,也可能大于n。

  解法1:使用散列表

    1.选择节点较少的链表(如果链表的长度未知,那么随便选择一个链表),将其所有节点的指针值保存在散列表中。

    2.遍历另一个链表,对于该链表中的每一个节点,检查散列表中是否已经保存了其节点指针。

    3.如果两个链表存在合并点,那么必定会在散列表中找到记录。

 

  解法2:使用栈 

    1.创建两个栈:一个用于第一个链表,另一个用于第二个链表。

    2.遍历第一个链表,把所有节点地址压入第一个栈。

    3.遍历第二个链表,把所有节点地址压入第二个栈。

    4.这时,两个栈分别包含了对应链表的节点地址

    5.比较连个栈的栈顶元素

    6.如果两者相等,那么弹出两个栈的栈顶元素并保存在临时变量中。

    7.继续上述过程,直至两个栈的栈顶元素不相等。

 

  解法3:复杂度更低的方法

    1.获得两个链表(L1和L2)的长度

    2.计算两个长度的差d

    3.从较长链表的表头开始,移动d步

    4.在两个链表中开始同时移动,直至出现两个后继指针值相等的情况

    5.时间复杂度为0(max(m,n))

    6。空间复杂度为O(1)

 

ListNode findIntersectingNode(ListNode list1, ListNode list2) {
        int L1 = 0, L2 = 0, diff = 0;
        ListNode head1 = list1; ListNode head2 = list2;
        while(head1 != null) {
            L1 += 1;
            head1 = head1.getNext();
        }
        while(head2 != null) {
            L2 += 1;
            head2 = head2.getNext();
        }
        
        if(L1 < L2) {
            diff = L2 - L1;
            head1 = list2;
            head2 = list1;
        } else {
            head1 = list1;
            head2 = list2;
            diff = L1 - L2;
        }
        
        for(int i = 0; i < diff; i++) {
            head1 = head1.getNext();
        }
        
        while(head1 != null && head2 != null) {
            if(head1 == head2) {
                return head1;
            }
            head1 = head1.getNext();
            head2 = head2.getNext();
        }
        return null;
    }

 

posted @ 2017-07-16 12:27  jiangfullll  阅读(145)  评论(0)    收藏  举报