每周完成一个 ARTS:
Algorithm: 每周至少做一个 LeetCode 的算法题
Review: 阅读并点评至少一篇英文技术文章
Tips: 学习至少一个技术技巧
Share: 分享一篇有观点和思考的技术文章
题图:Photo by Anders Jildén
难度:Easy
题意:
Given a linked list, determine if it has a cycle in it.
To represent a cycle in the given linked list, we use an integer pos
which represents the position (0-indexed) in the linked list where tail connects to. If pos
is -1
, then there is no cycle in the linked list.
示例 1:
Input: head = [3,2,0,-4], pos = 1
Output: true
Explanation: There is a cycle in the linked list, where tail connects to the second node.
示例 2:
Input: head = [1,2], pos = 0
Output: true
Explanation: There is a cycle in the linked list, where tail connects to the first node.
示例 3:
Input: head = [1], pos = -1
Output: false
Explanation: There is no cycle in the linked list.
Follow up:
Can you solve it using $O(1)$ (i.e. constant) memory?
解法 1:
这道题不要被题目描述所迷惑了,实际上测试函数并不会输入描述中所说的 pos
这个值。最简单的方法是,挨个儿把链表中的元素加入到一个列表中,如果一个元素已经出现在列表中,就说明有链表有圈。
代码:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
nodes = []
while head:
if head in nodes:
return True
nodes.append(head)
head = head.next
return False
这种做法时间复杂度为 $O(n)$,由于生成了一个另外的列表来存储节点,所以空间复杂度也为 $O(n)$。
解法 2:
题中有个 Follow up,要求使用常量时间复杂度来解决问题,那么就不能构造列表来存储节点了,需要换个思路。
我们借用生活中的一个例子,时钟,来理解第二种做法。大部分时钟都有时针和分针,不一定有秒针,时针和分针在同一个圈里,一块一慢,所以它们两个一定会有重合的时候。
类比到本题的情况,我们有一快一慢两个指针,如果有圈的话,这两个指针在圈里跑一定会有重合的时候,一旦重合,我们就可以判定这个链表有圈,否则没有圈。
代码:
# Definition for singly-linked list.
# class ListNode:
# def __init__(self, x):
# self.val = x
# self.next = None
class Solution:
def hasCycle(self, head: ListNode) -> bool:
fast, slow = head, head
while fast and fast.next:
fast, slow = fast.next.next, slow.next
if fast == slow:
return True
return False
这种做法时间复杂度 $O(n)$,空间复杂度 $O(1)$。
本周文章是来自于 Medium 的《The 50/30/10/10 Rule for How to Wake Up Earlier and Work on Your Dream》,关于如何早起。说实话,自从隔离以来,我的生物钟其实已经紊乱了,周中起床对我来说还能挣扎一会儿,周末完全不可能在 11 点之前起来。偶然在 Medium 上看到这篇文章,其实算是随机阅读的一篇,但我发现文章中说到的关于决心和习惯恰好对我有针对性。
作者在这篇文章中,把成功养成早起习惯归因于下面这四个原则:50% 的决心、30% 的准备、10% 的执行和 10% 的运气。
在这一部分,作者有一句话被非常多人标注了:
At some point, you’ve got to become obsessed with whatever your dream is. For me, that was writing.
但打动我的却是另外一句:
I knew if I wanted to be a better writer and change my life, I had to make it a priority. That became my determination for waking up earlier.
也许这句话更具有实际的意义。就像《人生护城河》中一直在强调的「以终为始」的思维方式,你需要找到一个终极的目标,并用这个终极的目标来指导你每天的生活,而每天睁开眼第一件事,就是起床。
在「准备」这一部分,作者给出了 5 点建议:
这 5 点不必全部采纳,但,我觉得他说的有道理🥱
在执行起床这一动作时,作者也给了三点建议:
关于第三点,我深有体会,大二一整年,我坚持把手机放在下铺,每天早上 6 点闹钟响了以后我就起来把它摁掉,因为怕吵到室友,然后刷牙洗脸,和朋友约好去学校的晨读室读英语(写着写着,脑袋里就有画面了,综教东面一楼左边那一间晨读室是我最喜欢去的,当然理教也有一间,每次经过中食堂都会去南校区门口的阿姨那买个鸡蛋灌饼还有一杯豆浆当早餐——不要吃粥啊,粥没有营养😂冬天的早晨站在北湖的桥上就能看到日出,夏天刚醒的北湖偶尔还能听见蛙声🐸+1s)。
计划总有赶不上变化的时候,这时候就需要有个搭伙的伴儿了。
最近经常会遇到一种情况,莫名地非常烦躁,什么也不想做,也没办法静下心来学习工作。没在家隔离的时候,这种状况很少发生,但也许是自我隔离的时间长了,人体的激素水平会有波动,影响心情。就像在写这篇文章之前,我就是处于这样一种状态:书桌前坐会儿、沙发上趴会儿、做几个深蹲或者俯卧撑,掏出手机刷刷微博、B 站,甚至觉得飞来飞去的小虫子也十分可恶,欲除之而后快。总之就是没办法沉下心来干活。
记得在第二十九周的打卡文章中,我翻译了一篇名为《The Most Underrated Productivity Technique Is Also the Simplest》的文章,文章给出了一个最简单的拯救工作日的建议。这个建议只有两个步骤:
参考我上述的表现,很明显,我一直在尽力避免第一步的发生。
在经历了漫长的纠结过后,我决定试试先坐下来,而且告诉自己,就干 5 分钟,5 分钟之后再说。
然后就有了你看到的这篇文章 😛
最近在阅读「辉哥奇谭」公众号主张辉的一本书《人生护城河》,看起来像鸡汤,但仔细想想背后都有逻辑支撑。现在还没有读完,但我想把目前为止产生的一些想法分享给大家。
这一部分非常长,大概有 5000 字,我把它单独拎出来成文了,可以看这里。