C#LeetCode刷题之#160-相交链表(Intersection of Two Linked Lists)

C#LeetCode刷题之#160-相交链表(Intersection of Two Linked Lists)

问题

编写一个程序,找到两个单链表相交的起始节点。

例如,下面的两个链表:

A:          a1 → a2
                   ↘
                     c1 → c2 → c3
                   ↗            
B:     b1 → b2 → b3
在节点 c1 开始相交。

注意

如果两个链表没有交点,返回 null.
在返回结果后,两个链表仍须保持原有的结构。
可假定整个链表结构中没有循环。
程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。

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, return null.
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.

示例

public class Program {

    public static void Main(string[] args) {
        var headA = new ListNode(1) {
            next = new ListNode(2) {
                next = new ListNode(1) {
                    next = new ListNode(2) {
                        next = new ListNode(3)
                    }
                }
            }
        };

        var headB = new ListNode(1) {
            next = new ListNode(2) {
                next = new ListNode(3) {
                    next = headA.next.next
                }
            }
        };

        var res = GetIntersectionNode(headA, headB);
        ShowArray(res);

        res = GetIntersectionNode2(headA, headB);
        ShowArray(res);

        res = GetIntersectionNode3(headA, headB);
        ShowArray(res);

        Console.ReadKey();
    }

    private static void ShowArray(ListNode list) {
        var node = list;
        while(node != null) {
            Console.Write($"{node.val} ");
            node = node.next;
        }
        Console.WriteLine();
    }

    private static ListNode GetIntersectionNode(ListNode headA, ListNode headB) {
        //LeetCode超时未AC
        var nodeA = headA;
        while(nodeA != null) {
            var nodeB = headB;
            while(nodeB != null) {
                if(nodeA == nodeB) {
                    return nodeA;
                }
                nodeB = nodeB.next;
            }
            nodeA = nodeA.next;
        }
        return null;
    }

    private static ListNode GetIntersectionNode2(ListNode headA, ListNode headB) {
        var nodeA = headA;
        var nodeB = headB;
        var set = new HashSet<ListNode>();
        while(nodeA != null) {
            set.Add(nodeA);
            nodeA = nodeA.next;
        }
        while(nodeB != null) {
            if(set.Contains(nodeB)) {
                return nodeB;
            }
            nodeB = nodeB.next;
        }
        return null;
    }

    private static ListNode GetIntersectionNode3(ListNode headA, ListNode headB) {
        var pointA = headA;
        var pointB = headB;
        if(headA != null && headB != null) {
            while(pointA != pointB) {
                if(pointA == null) {
                    pointA = headB;
                } else {
                    pointA = pointA.next;
                }
                if(pointB == null) {
                    pointB = headA;
                } else {
                    pointB = pointB.next;
                }
                if((pointA == null) && (pointB == null)) {
                    return null;
                }
            }
            return pointA;
        } else {
            return null;
        }
    }

    public class ListNode {
        public int val;
        public ListNode next;
        public ListNode(int x) { val = x; }
    }

}

以上给出3种算法实现,以下是这个案例的输出结果:

1 2 3
1 2 3
1 2 3

分析:

显而易见,GetIntersectionNode 的时间复杂度为: O(n^{2}) ,GetIntersectionNode2 和GetIntersectionNode3 的时间复杂度为:O(n)

本文由 .Net中文网 原创发布,欢迎大家踊跃转载。

转载请注明本文地址:https://www.byteflying.com/archives/3824

发表评论

登录后才能评论