leetcode

来源:互联网 发布:网络语call是什么意思 编辑:程序博客网 时间:2024/05/21 12:42

题目

Write a program to find the node at which the intersection of two singly linked lists begins.


For example, the following two linked lists:

A:          a1 → a2                   ↘                     c1 → c2 → c3                   ↗            B:     b1 → b2 → b3

begin to intersect at node c1.


Notes:

  • If the two linked lists have no intersection at all, returnnull.
  • The linked lists must retain their original structure after the function returns.
  • You may assume there are no cycles anywhere in the entire linked structure.
  • Your code should preferably run in O(n) time and use only O(1) memory.

题意

写一个程序,找到两个链表的交集开始的地方(在某处指向同一个结点,即在内存中相同)。


分析及解答

解法1:(观察规律,利用性质)

  • 【利用长度】长度(headA) =  长度(headA_front) +  长度(headA._common), 其中headA_front 表示非交集部分,headA_common表示交集部分。   ---->  同样我们可以得到长度(headB) =  长度(headB_front) +  长度(headB._common)。
  • 【思路】因为 长度(headA._common) = 长度(headB._common)。(1)如果存在交集,那么开始点之后的结点都是交集,所以我们可以从后向前判断,直到找到第一个不同的点(可利用栈)。(2)我们也可以正向判断,但是需要确保两个链表如果进行比较,他们的共同的结点可正好得以比较,于是想到了长度对齐的方式通过将较长链表的多出的结点去掉,进而将两个链表调整为同样的长度)。

public class Solution {    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {        int lenA=0, lenB=0;        ListNode dum = headA, dum2 = headB;        while (dum!=null) {            lenA++;            dum=dum.next;        }        dum=headB;        while (dum!=null) {            lenB++;            dum=dum.next;        }        dum=headA;        dum2=headB;//关键点:如果有交集一定是从某个地方到末尾(等长)。        if (lenA>lenB) {            for (int i=0; i<lenA-lenB; i++) {                dum=dum.next;            }        } else {            for (int j=0; j<lenB-lenA; j++) {                dum2=dum2.next;            }        }        while (dum!=null) {            if (dum==dum2) return dum;            dum=dum.next;            dum2=dum2.next;        }        return null;    }}

解法2:(2个栈,从后向前比较)

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {      if(headA == null || headB == null){return null;}LinkedList<ListNode> stackA = new LinkedList();ListNode pointer = headA;while(pointer != null){stackA.push(pointer);pointer = pointer.next;}LinkedList<ListNode> stackB = new LinkedList();pointer = headB;while(pointer != null){stackB.push(pointer);pointer = pointer.next;}pointer = null;while(!stackA.isEmpty() && !stackB.isEmpty()){//当作栈来使用时,则list第一个元素为栈顶元素。if(stackA.peekFirst() == stackB.peekFirst()){pointer = stackA.pop();stackB.pop();}else{break;}}return pointer;    }