「这是我参与11月更文挑战的第 11 天,活动详情查看:2021最后一次更文挑战」
刷算法题,从来不是为了记题,而是练习把实际的问题抽象成具体的数据结构或算法模型,然后利用对应的数据结构或算法模型来进行解题。个人觉得,带着这种思维刷题,不仅能解决面试问题,也能更多的学会在日常工作中思考,如何将实际的场景抽象成相应的算法模型,从而提高代码的质量和性能
两个链表的第一个公共结点
题目来源:LeetCode-160. 相交链表
题目描述
输入两个链表,找出它们的第一个公共节点
如下面的两个链表:
在节点 c1 开始相交
示例
示例 1
1 | css复制代码输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3 |
示例 2
1 | css复制代码输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1 |
示例 3
1 | css复制代码输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2 |
提示:
- 如果两个链表没有交点,返回
null
. - 在返回结果后,两个链表仍须保持原有的结构
- 可假定整个链表结构中没有循环
- 程序尽量满足 O(n) 时间复杂度,且仅用 O(1) 内存
- 本题与主站 160 题相同:leetcode-cn.com/problems/in…
解题
解法一:散列表
思路
这种找公共节点,跟找环的入口点差不多,所以解题的思路也差不多,过程是
- 先遍历链表l1,并将结点记录到散列表中
- 再遍历l2,遍历的过程中,判断l2中的结点是否在散列表中,第一个在散列表中存在的结点,就是我们要找的第一个公共节点
代码
1 | go复制代码type ListNode struct { |
解法二:双指针
思路
这种感觉很难想到,当花一定的时间还是想不到怎么做的时候,可以去看别人的做法。毕竟有很多解法很难想到,主要是理解思路,知道这种问题,有这种解法,不必过于死磕
首先我们知道,如果两个链表相交,那么它们第一个相交点之后的长度是相等的。只要我们能消除相交之前部分的长度差,当两个指针相等的时候,就是它们的相交点,具体过程如下:
- 指针pA指向 A 链表,指针 pB 指向 B 链表,依次往后遍历
- 如果 pA 到了末尾,则让pA指向B链表的头结点( pA = headB )继续遍历
- 如果 pB 到了末尾,则则让pB指向A链表的头结点( pB = headA )继续遍历
- 比较长的链表指针指向较短链表head时,长度差就消除了
文字描述很抽象,看图
1 | ini复制代码//双指针实现 |
本文转载自: 掘金