❗️LeetCode_160_相交链表
❗️注意本题与剑指Offer_68_树中两个节点的最低公共祖先
有联系
题目描述: 1 2 3 4 5 6 7 8 9 10 11 输入两个链表,找出它们的第一个公共节点。 输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 输出:Reference of the node with value = 8 输入解释:相交节点的值为 8 (注意,如果两个列表相交则不能为 0)。从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。 注意: 1. 如果两个链表没有交点,返回 null. 2. 在返回结果后,两个链表仍须保持原有的结构。 3. 可假定整个链表结构中没有循环。 4. 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存。
解法1: 用蛮力法,在第一个链表上顺序遍历每个节点,每遍历到一个节点,就在第二个链表上顺序遍历每个节点。如果在第二个链表上有一个节点和第一个链表上的节点一样,则说明两个链表在这个节点上重合,于是就找到了它们的公共节点。如果第一个链表的长度为m,第二个链表的长度为n,那么显然该方法的时间复杂度是O(mn)
解法2: 如果两个链表有公共节点,那么公共节点出现在两个链表的尾部,如果我们从两个链表的尾部开始往前比较,那么最后一个相同的节点就是我们要找的节点。于是我们就能想到用栈的特点来解决这个问题:分别把两个链表的节点放入两个栈里,这样两个链表的尾节点就位于两个栈的栈顶,接下来比较两个栈顶的节点是否相同,如果相同,则把栈顶弹出接着比较下一个栈顶,直到找到最后一个相同的节点。空间复杂度为O(m+n),时间复杂度也是O(m+n),和蛮力法相比,时间效率得到了提高,相当于用空间消耗换取了时间效率
⭐️问题:当两个链表的长度不相同时,如果我们从头开始遍历,那么到达尾节点的时间就不一致
解法3: 首先遍历两个链表得到它们的长度,就能知道哪个链表比较长,以及长的链表比短的链表多几个节点。在第二次遍历的时候,在较长的链表上先走若干步,接着同时在两个链表上遍历,找到的第一个相同的节点就是它们的第一个公共节点。时间复杂度为O(m+n),但我们不再需要辅助栈,因此提高了空间效率
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 class Solution {public : unsigned int GetListLength (ListNode* pHead) { unsigned int nLength = 0 ; ListNode* pNode = pHead; while (pNode != NULL ) { ++nLength; pNode = pNode -> next; } return nLength; } ListNode *getIntersectionNode (ListNode *headA, ListNode *headB) { unsigned int nLength1 = GetListLength (headA); unsigned int nLength2 = GetListLength (headB); int nLengthDif = nLength1 - nLength2; ListNode* pListHeadLong = headA; ListNode* pListHeadShort = headB; if (nLength2 > nLength1) { pListHeadLong = headB; pListHeadShort = headA; nLengthDif = nLength2 - nLength1; } for (int i = 0 ;i < nLengthDif;i++) { pListHeadLong = pListHeadLong -> next; } while (pListHeadLong != NULL && pListHeadShort != NULL && pListHeadLong != pListHeadShort) { pListHeadLong = pListHeadLong -> next; pListHeadShort = pListHeadShort ->next; } ListNode* pFirstCommonNode = pListHeadLong; return pFirstCommonNode; } };
解法4: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 class Solution {public : ListNode *getIntersectionNode (ListNode *headA, ListNode *headB) { ListNode* l1 = headA,*l2 = headB; while (l1 != l2) { l1 = l1 ? l1->next : headB; l2 = l2 ? l2->next : headA; } return l1; } };