每周完成一个 ARTS:
Algorithm: 每周至少做一个 LeetCode 的算法题
Review: 阅读并点评至少一篇英文技术文章
Tips: 学习至少一个技术技巧
Share: 分享一篇有观点和思考的技术文章
题图:
%>%
难度:Medium
题意:Given a matrix of m x n elements (m rows, n columns), return all elements of the matrix in spiral order.
示例 1:
Input:
[
[ 1, 2, 3 ],
[ 4, 5, 6 ],
[ 7, 8, 9 ]
]
Output: [1,2,3,6,9,8,7,4,5]
示例 2:
Input:
[
[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12]
]
Output: [1,2,3,4,8,12,11,10,9,5,6,7]
解法:
这道题原本我并没有在 LC 上找到,但是我的好朋友郭瑞在做面试题,向我求助,于是我尝试着给他解答了一下,结果后来在 LC 上找到原题了。这题看起来比较难,其实也确实比较难(Medium),我一眼看过去感觉像是本科的时候做的 C 语言练习题,当时北理工的 C 语言真是学得我痛不欲生。。。
闲言少叙,我们来看一下这道题。题意其实非常好理解,只是理解完了不知道怎么下手。我最开始的思路是,找每一行数字的规律,但是题目中并没有说这个矩阵是按照数字顺序排列的,所以应该不能这么做。
转换一下思路,我们知道,螺旋是自然中最常见的分形规则之一,所以同理,这个题目中的螺旋可以拆解成四个动作,即 →、↓、←、↑。每转一圈,剩下的操作其实都和上一圈相同,只是大小不同,也即边界不同。随即我们就有了思路,就是可以通过控制边界的方法,重复执行这个四个动作,来完成对矩阵的螺旋展开。
我们先把矩阵的上下左右四个边界记录下来,然后对每一条边分别执行遍历操作,将这条边的元素放入到 result
中去,每执行完一条边,就将对应的边界往里移,直到某一条边界与它对面的边界重合(需要超过),那么就表示没有边界可以再减,我们的遍历就执行完毕了。
代码:
class Solution:
def spiralOrder(self, matrix: List[List[int]]) -> List[int]:
if matrix == []:
return []
result = []
n, m = len(matrix), len(matrix[0])
u, d, l, r = 0, n-1, 0, m-1
while True:
# →
for j in range(l, r + 1):
result.append(matrix[u][j])
u += 1
if u > d: break
# ↓
for i in range(u, d + 1):
result.append(matrix[i][r])
r -= 1
if r < l: break
# ←
for j in range(r, l - 1, -1):
result.append(matrix[d][j])
d -= 1
if d < u: break
# ↑
for i in range(d, u - 1, -1):
result.append(matrix[i][l])
l += 1
if l > r: break
return result
时间复杂度 $O(mn)$,空间复杂度 $O(mn)$。
大概是在 2018 年的时候,我偶然间在播客应用中看见《The Minimalists Podcast》被推荐,于是开始了自己(伪)极简主义者的践行之路。
对多多少少接触过或者听过「极简主义」这个词的人来说,大概极简主义就是尽量少的东西、干净简洁的衣柜和书桌、极简的设计和审美观等等这些。甚至很多人一听到「极简主义」就会想到 MUJI 或者 IKEA。的确,日系和北欧的极简设计经常会有种让人沉静的感觉。但他们也还不是「极简主义」。
那么什么是「极简主义」呢?Manuel Moreale 在他的网站上写了一系列文章来介绍极简主义和他本人的践行方法,今天要介绍的就是这个系列的开篇《Introduction: What Minimalism is and is not》。
在这篇文章中,作者提到:
To me, Minimalism has nothing to do with anything visual. That might sound a bit strange since most of the online world seems to be focused on minimal aesthetics, minimal design, minimal fashion, and on and on and on.
正如我之前所说,极简的审美、极简的设计、极简的潮流,这些都不是「极简主义」。作者认为,当前对「极简主义」的定义已经演变成一种生活方式和一系列美学规则的奇怪组合,这些规则支配着人们如何设计衣柜、网站和房屋。
「极简主义」对于作者来说,更多的是一种 Mindset,是一种指导原则,而把极简的 Mindset 应用到生活上,则是某种生活方式,而这种生活方式,又恰恰是「极简主义」的一个副产品。你可以成为一个看起来并不像极简主义者的极简主义者。
举个例子:一个极简主义者的衣柜看起来非常「极简」,并不是因为 TA 是个极简主义者,而是因为 TA 把极简主义的 Mindset 应用到了买衣服上。TA 的目的并不是成为一个极简主义者,而是让 TA 的衣柜尽可能的 functional 且 optimised,一个「极简的衣柜」则是这样的行为的产物。
Manuel Moreale 在这个系列文章中提到了更多关于「极简主义」的信息:
Introduction: What Minimalism is and is not
Chapter 1: The Mindset
Chapter 2: Design doesn’t matter
Chapter 3: Function over Form
Chapter 4: Digital and Physical
Chapter 5: Objects are not everything
Closing thoughts: Living a simple life it’s not easy
欢迎搜索查看。
%>%
在使用 R 进行数据处理的过程中,或多或少都要编写一些输入输出代码,按照传统的书写习惯,我们往往会引入很多的中间变量,或者嵌套很多的函数来进行一次性的输入输出。前者会造成不必要的内存浪费,尤其是原始数据量很大的时候,而后者虽然避免了内存浪费,但是大量嵌套在一起的函数往往会让代码很难读,也会给调试和复用造成困扰。
R 中有一个使用得很频繁的管道函数,写作 %>%
,来自于 magrittr
包。由于现在大多数项目包都默认会调用 magrittr
包,所以也不用再手动去调用了。具体书写,举个例子:
ts.trf <- ts.data %>% log() %>% diff(n_diffs)
上面这个操作,就是把 ts.data
作为第一个参数,传递给 log()
函数,再将 log()
计算的结果,作为第一个参数,传递给 diff()
函数,而 n_diffs
就是 diff()
的第二个参数了;最后,将 diff()
的计算结果,返回赋值给 ts.trf
。
其实这是一个对非平稳序列进行平稳化的常用操作,这样写,避免了中间变量的使用和多个函数的嵌套,简单、清晰、明了。
由于疫情的影响,这周开始,法国要求所有企业的员工,如无必要,避免去公司上班,于是我也顺理成章地开启了「愉快的」宅家工作。然而,就像跃哥这篇文章中讲到的,我也遭遇了「在家办公的丑陋真相」。正常的工作节奏被打乱、生活和工作越来越区分不开,还要面对无孔不入的孤独和寂寞……不过经过几天的尝试之后,我处理得还不错,在这里分享几个思路。
思路一:改变工作环境。在家工作最容易让人降低效率的原因是,家的环境是一个容易让你放松的环境,所以第一条思路就是改造你的工作空间,让它不要那么舒适,至少不要让你在工作的时候容易睡着。可类比「头悬梁、锥刺股」的做法(逃。。另外,注意力是稀缺资源,所以在家工作的时候,我们应该尽量避开干扰源,比如电视或者手机。对于后者,可以设置 iOS 的「屏幕使用时间限制」或者在 Android 的「数字健康」中开启「专注模式」,来减少手机上的干扰。
思路二:调整心理状态。接上一条思路,我在《段子来了》播客中听到过一些有关远程工作的段子,比如不用洗头化妆就可以开始工作、穿着睡衣做项目展示等等。其实这些反映了人的心理状态,所以思路二就是,通过一些行为来改变在家工作时的心理状态。我的经验之一就是,在家工作同样也要穿得相对正式一些。
思路三:有一个相对固定的工作流程。在家工作的最大的一个好处就是,你没有在办公室中的那些条条框框的束缚,所以你可以决定何时开始工作,以及如何工作。但最好要有一个相对固定的工作流程,相当于给自己设定一个工作时间段,然后每天用同样的流程来让自己进入工作模式。这样可以大大降低进入工作模式需要消耗的注意力。
思路四:和同事或者工作团队保持正常的沟通。一来可以降低你的孤独感(尤其像我这样一个人在家里隔离的),二来保持沟通也是保证正常工作进度的最好方式。
PS:骂方方的人非蠢即坏 🤬。