leetcode 160 相交链表

一:time:O(m+n) space:O(m+n)

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        //time O (m+n) space O(m+n)
        Set<Integer> set = new HashSet<>();//具有自动去重功能
        int sum = 0;
        while (headA != null) {
            set.add(headA.hashCode());
            headA = headA.next;
            sum++;
        }
        while (headB != null) {
            set.add(headB.hashCode());
            sum++;
            if (sum != set.size()) return headB;
            headB = headB.next;
        }
        return null;
    }

 

二:time:O(m+n) space:O(1)

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) return null;
        int lenA = getLength(headA), lenB = getLength(headB);
        if (lenA > lenB) {
            for (int i = 0; i < lenA - lenB; ++i) headA = headA.next;
        } else {
            for (int i = 0; i < lenB - lenA; ++i) headB = headB.next;
        }
        while (headA != null && headB != null && headA != headB) {
            headA = headA.next;
            headB = headB.next;
        }
        return headA;
    }
    public int getLength(ListNode head) {
        int cnt = 0;
        while (head != null) {
            ++cnt;
            head = head.next;
        }
        return cnt;
    }

因为相交之后的结点数目都是一样的,所以可以先得到两个结点长度,在把长链表减去多的那部分,再一一比对是否相等就行。

 

这道题还有一种特别巧妙的方法,虽然题目中强调了链表中不存在环,但是我们可以用环的思想来做,我们让两条链表分别从各自的开头开始往后遍历,当其中一条遍历到末尾时,我们跳到另一个条链表的开头继续遍历。两个指针最终会相等,而且只有两种情况,一种情况是在交点处相遇,另一种情况是在各自的末尾的空节点处相等。为什么一定会相等呢,因为两个指针走过的路程相同,是两个链表的长度之和,所以一定会相等。这个思路真的很巧妙,而且更重要的是代码写起来特别的简洁,参见代码如下:

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        if (headA == null || headB == null) return null;
        ListNode a = headA, b = headB;
        while (a != b) {
            a = (a != null) ? a.next : headB;
            b = (b != null) ? b.next : headA;
        }
        return a;
    }

 

posted @ 2022-01-10 11:26  ou尼酱~~~  阅读(71)  评论(0)    收藏  举报