什么是 ARTS?
- 算法(Algorithm): 每周至少一道 LeetCode 算法题,加强编程训练和算法学习
- 阅读(Review): 阅读并点评至少一篇英文技术文章,提高英文水平
- 技巧 (Tip):学习至少一个技术技巧,总结、归纳日常工作中遇到的知识点
- 分享(Share):分析一篇有观点和思考的技术文章,建立影响力,输出价值观
时间周期
11月21日止11月28日
一:算法
leetCode题目地址:https://leetcode.cn/problems/intersection-of-two-linked-lists/
编写一个程序,找到两个单链表相交的起始节点。
前置知识
- 链表
- 双指针
解法一:哈希法
有A,B这两条链表,先遍历其中一个,比如A链表,并将A中的所有节点存入哈希表。
遍历B链表,检查节点是否在哈希表中,第一个存在的就是相交节点
- 伪代码
// 存放A链表的所有节点的地址
date = new Set()
while A 不为空 {
哈希表中添加A链表当前节点
A指针向后移动
}
while B不为空 {
if 如果哈希表中含有B链表当前节点
return B
B指针向后移动
}
// 两条链表没有相交点
return null
JavaScript代码
/**
* @param {ListNode} headA
* @param {ListNode} headB
* @return {ListNode}
*/
let getIntersectionNode = function (headA, headB) {
let data = new Set()
while (headA !== null) {
data.add(headA)
headA = headA.next
}
while (headB !== null) {
if (data.has(headB)) {
return headB
}
headB = headB.next
}
return null
};
复杂度分析
- 空间复杂度: O(N)
- 时间复杂度: O(N)
解法二:双指针
- 例如使用a,b两个指针分别指向A,B这两条链表,两个指针相同的速度向后移动
- 当a到达链表的尾部时,重定位到链表B的头节点
- 当b到达链表的尾部时,重定位到链表A的头节点
- a,b指针相遇的点为相交的起始节点,否则没有相交点
为什么a,b指针相遇的点一定是相交的起始节点?我们证明一下:
- 将两条链表按相交的起始节点继续截断,链表1为:A + C,链表2为:B + C
- 当a指针将链表1遍历完后,重定位到链表B的头节点,然后继续遍历直至相交点(a指针遍历的距离为A+C+B)
- 同理b指针遍历的距离为B+C+A
伪代码
a = headA
b = headB
while a,b指针不相等时 {
if a指针为空时:
a指针重定位到链表的B的头节点
else:
a指针向后移动一位
if b指针为空时:
b指针重定位到链表A的头节点
else:
b指针后移动一位
}
return a
JavaScript Code
let getIntersectionNode = function (headA, headB) {
let a = headA
let b = headB
while (a != b) {
if (a === null) {
a = headB
} else {
a = a.next
}
if (b === null) {
b = headA
} else {
b = b.next
}
}
return a
};
Python Code:
class Solution:
def getIntersectionNode(self, headA: ListNode, headB: ListNode) -> Optional[ListNode]:
a, b = headA, headB
while a != b:
a = a.next if a else headB
b = b.next if b else headA
return a
Go Code:
func getIntersectionNode(headA, headB *ListNode) *ListNode {
// a=A(a单独部分)+C(a相交部分); b=B(b单独部分)+C(b相交部分)
// a+b=b+a=A+C+B+C=B+C+A+C
a := headA
b := headB
for a !=b {
if a == nil {
a = headB
} else {
a = a.Next
}
if b == nil {
b = headA
} else {
b = b.Next
}
}
return a
}
算法思考:
- JavaScript无论是从时间复杂度,还是空间复杂度上来说,都不是最优解,真要追求极致性能,javaScript是真的不够用
- Python运行时间上最慢,但是空间上还是可以的
- 表扬一下Go,无论是空间,还是时间上,都是极其强悍的
二:阅读
Web 开发的未来是边缘网络
三:技巧
小黄鸭调试法
日记的作用
四:分享
《什么是高级工程师?》
分享理由:
- 有人带,有代码规范,1个足够聪明的小朋友在1年内就能写出很好的代码了,这时候,他和高级工程师的区别在哪里?文中给出了一个思路
- 高级工程师,这个title进入公司的人,写代码只是他的一部分工作,更多的工作是那些工程实践知识,那些经验比让他写具体的一个业务,对公司产生的价值更大
下面是我的翻译文章链接:https://www.jianshu.com/p/3bd94b5e10cb