CodingTour
ARTS #35

Algorithm

本周选择的算法题是:First Missing Positive

规则如下:

Given an unsorted integer array, find the smallest missing positive integer.

Example 1:

Input: [1,2,0]
Output: 3

Example 2:

Input: [3,4,-1,1]
Output: 2

Example 3:

Input: [7,8,9,11,12]
Output: 1

Note:

Your algorithm should run in O(n) time and uses constant extra space.

Solution

我实现的方案:

Runtime:32 ms,快过 79%。

Memory:12.7 MB,低于 100%。

class Solution:
    def firstMissingPositive(self, nums: List[int]) -> int:
        i, max_num = 0, len(nums)
        while i < max_num:
            if 0 < nums[i] <= max_num and nums[i] != i+1 and nums[i] != nums[nums[i]-1]:
                right_place = nums[i]-1
                nums[i], nums[right_place] = nums[right_place], nums[i]
            else:
                i += 1
        
        for i in range(max_num):
            if nums[i] != i+1:
                return i+1
        return max_num+1

Review

Goodbye, Clean Code

作者在文章中阐明了一个观点:代码的干净不是重点,从系统复杂度中解脱才是目的。

那干净的代码会起相反的作用吗?某些情况下的确如此,需要指出的是所有的前提都是你先发现了一些包含大量重复的“脏”代码,然后期望将它改造成“干净”的代码。

为此我们需要:

  • 找出重复的代码行
  • 试图定义一些抽象
  • 对于一些相同的行为,做出公共代码,然后组合调用

这一切都只是为了减少重复。其中的陷阱在于重构后的代码不一定会满足旧代码的指标,比如一些快速“应付”需求变更的场合,旧代码无疑会更容易处理,而新代码需要投入更多的维护成本。

另外一点是会留下“我是会写干净、整洁代码的人”的刻板印象,这个印象会使人“看见脏”的能力不断得到增强,甚至能够从“无”中发现可“抽象”的东西,这也是一个陷阱。

作者基于此批判那些“为了干净而干净”的行为,代码应该不止于“干净”,而是真正从系统复杂度中解脱。为此当我们要修改代码库时,如果不能做到对修改后产生的行为有绝对的把握,则应该在大脑里铭记这一点:我是不是忽略了什么?是否还可以满足质量指标?权当是一种防护机制。

Tip

审查 Python 对象:

test = [1, 3, 5, 7]
print( dir(test) )

# ['__add__', '__class__', '__contains__', '__delattr__', '...']

使用 * 操作符拆包函数参数:

def test(x, y, z):
	print(x, y, z)

testDict = {'x': 1, 'y': 2, 'z': 3} 
testList = [10, 20, 30]

test(*testDict)
test(**testDict)
test(*testList)

#1-> x y z
#2-> 1 2 3
#3-> 10 20 30

Share

高效学习:面对枯燥和量大的知识

如何面对枯燥的知识:

  • 找到应用场景
  • 带着问题学习,增加反馈和成就感
  • 找大牛解答你的问题

如何面对大量的知识:

  • 找到可重复的路径
  • 用成就感来推动学习

实用技巧:

  • 用不同的方式学同一个东西 - 比如看书、听课、写博客、讲课等
  • 不要被打断 - 保持专注
  • 总结压缩信息 - 用表格、图示或脑图帮你理解
  • 关联到已知的技能树上
  • 用教的方式来学习 - 提高对自己学习的要求
  • 学以致用 - 在现实中找场景,深化学习
  • 不要记忆 - 用方法论推导结论
  • 多犯错误 - 通过错误总结教训

高效沟通:Talk 和 Code 同等重要

能力是树根,沟通是树干和枝叶。

沟通需要注意的问题:

  • “编码”和“解码”的方式不同,造成听和说的人不能互相理解
  • 不同的场景要使用不同的沟通方式
  • 面对不同的人也要使用不同的沟通方式
  • 可以借助听者的反馈来达成共识
  • 重视信息的源头

高效沟通:沟通阻碍和应对方法

沟通阻碍:

  • 没听懂却不好意思问 - 沟通效率的关键不在快,而在准确
  • 说太多与主题无关的无效信息 - 不要绕弯子,有话直说
  • 沟通成了单向灌输 - 寻找对方的兴趣点,降低表达自己真实想法的门槛,培养大家畅所欲言的自由环境,让其他人有参与感
  • 有时会为了一些琐碎的小事争论不休 - 表达方式、沟通态度出了问题,要以一种平等且互相尊重的态度进行交流
  • 二手信息使人做出严重的错误判断 - 到信息的源头去求证,向当事人去求证
  • 信息不对称只有短期利益 - 好团队需要有创造力,能让员工自我成长,让信息公开透明