[LeetCode] Intersection of Two Linked Lists
来源:互联网 发布:失恋巧克力职人 知乎 编辑:程序博客网 时间:2024/06/10 21:02
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.
要说在LeetCode上刷题最让我受益匪浅的地方,大概就是链表相关的问题了吧。以前对于链表的认识很浅,基本只够应付“说说链表和数组的优缺点”这种问题,真正应用到的机会很少。来了LeetCode才发现,链表还可以这么玩,而且玩的这么溜。
针对这道题,我想了很久都想不到O(n)时间复杂度的做法(我是真的菜),于是就撸了一个暴力枚举的做法:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { ListNode* tempA; ListNode* tempB; while(headA) { tempA=headA; tempB=headB; while(tempB) { if(tempA==tempB)return tempA; tempB=tempB->next; } headA=headA->next; } return NULL; }};
毕竟跟指针相关的代码很容易出错,为了确认这样写的逻辑有没有问题,我就试探性地交了一发,居然直接AC了...这要是在ACM,怎么也是TLE吧。
感觉打ACM的人是不是真的不应该做LeetCode,做多了AC多了,你真的就没有对罚时的恐惧了,对时间复杂度也视而不见了...
当然这道题还没有结束,上面的代码明显不是最优的。想了一下其实用哈希基本就可以降复杂度了,于是乎再来一发:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { unordered_set<ListNode*> s; while(headA) { s.insert(headA); headA=headA->next; } while(headB) { if(s.find(headB)!=s.end())return headB; headB=headB->next; } return NULL; }};哈哈哈过了,用时也还算低,但是直觉告诉我这不是出题人的本意,肯定还有更巧妙的做法。果不其然,围观了一下大佬的做法,简直变身小迷弟给大佬疯狂打call。这是大佬的代码:
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */class Solution {public: ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { if (!headA||!headB) return NULL; ListNode *a=headA,*b=headB; while(a!=b) { a=a?a->next:headB; b=b?b->next:headA; } return a; }};两个字:优美
题目保证不出现环,然后大佬就把两个链首尾相连构造成环。有两个理解上的要点:
- 假设A长度m,B长度n,两个指针都会在m+n次循环后同时抵达空指针,使得a!=b不成立退出循环,防止了死循环的出现,返回NULL。
- 假设倒数第k个点是交集,由于交点之后的点是共用的,所以两个指针都会在m+n-k次循环后抵达相同节点,使得a!=b不成立退出循环,返回交点指针。
如果大家理解上有困难,可以画个图模拟一下。这种想法光是理解对我们来说都挺费劲的,大佬还能用短短几行代码就将其实现,实在是让人佩服。
这道题也让我认识到,自己对指针、链表的认识还需要加强。
阅读全文
0 0
- [leetcode] [leetcode]Intersection of Two Linked Lists
- 【LeetCode】Intersection of Two Linked Lists
- LeetCode: Intersection of Two Linked Lists
- [Leetcode] Intersection of Two Linked Lists
- [Leetcode]Intersection of Two Linked Lists
- LeetCode:Intersection of Two Linked Lists
- leetcode: Intersection of Two Linked Lists
- Leetcode: Intersection of Two Linked Lists
- Intersection of Two Linked Lists--leetcode
- [leetcode]Intersection of Two Linked Lists
- leetcode:Intersection of Two Linked Lists
- leetcode之Intersection of Two Linked Lists
- 【Leetcode】:Intersection of Two Linked Lists
- leetcode Intersection of Two Linked Lists
- [LeetCode]Intersection of Two Linked Lists
- leetcode: Intersection of Two Linked Lists
- 【LeetCode】Intersection of Two Linked Lists
- LeetCode Intersection of Two Linked Lists
- 第十二周 项目验证算法 (5)拓扑排序算法验证
- 在测试batik源码中的问题
- 两种方法上传本地文件到github
- 第十三周项目1-验证算法(2)
- STM8L15x系列DAC的使用
- [LeetCode] Intersection of Two Linked Lists
- 常用正则表达式
- JDBC插入Timestamp类型数据时精度问题
- Quick的信号与槽
- 时间戳转格式化的时间
- vscode —— 编码缩进空格转为tab
- Oracle 数据泵(IMPDP/EXPDP)导入导出总结
- HTML常用
- java虚拟机中的内存分配和作用