1 概述
ARTS 是耗子叔发起的编程挑战:
每周完成一个ARTS: 每周至少做一个 leetcode 的算法题、阅读并点评至少一篇英文技术文章、学习至少一个技术技巧、分享一篇有观点和思考的技术文章。(也就是 Algorithm、Review、Tip、Share 简称ARTS)
2 Algorithm
本周 leetcode 挑选了3个与数组相关的题。
2.1 3Sum
问题描述:
Given an array nums of n integers, are there elements a, b, c in nums such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.
见15-3 Sum。
难度:中等。
问题解析:
- 题目要求的是所有三元组(a, b, c)使得
a + b + c = 0
。 - 这道题的难点在于如何去重。为了避免重复添加,我将原数组进行排序,这样保证挑出的三元组满足
a <= b <= c
。 - 为了提升效率,先将每个元素的索引记在一个HashMap中。两重循环尝试 a 和 b,在HashMap中查找-(a+b),即为 c。
- a 和 b 可以唯一确定 c,使用
HashMap<Integer, HashSet<Integer>>
去重,如果 b 在由 a 定位到的HashSet
中,则三元组已存在。
实现:
Java
实现见github,耗时:308ms。
解法二:
后来我了解到另一种优雅的解决方案——双指针。基本思路如下:
- 将原数组排序。
- 遍历数组元素作为 a。
- 然后将当前元素后一个元素作为 b 的起始位置,最后一个元素作为 c 的起始位置。
- 如果 a + b + c > 0,则将 c 向左移动。
- 如果 a + b + c < 0,则将 b 向右移动。
该方案还能很好的去重,而且节省了HashMap
的开销。Java
实现见github,耗时:104ms。
2.2 Majority Element
Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.
You may assume that the array is non-empty and the majority element always exist in the array.
难度:简单。
问题解析:
- 题中给定了两个限制条件让题目变得非常简单:1.数组非空 2.主元素一定存在。
- 主元素是出现次数超过一半的元素,那么将主元素与其他元素一一配对之后肯定剩余一些主元素。我们可以想象这是一种抵消,最坏情况下,所有其他元素都抵消一个主元素,主元素有剩余。
实现:
Java
实现见github。代码比较简单也贴在这里吧:
|
|
2.3 First Missing Positive
Given an unsorted integer array, find the smallest missing positive integer.
难度:困难。
问题解析:
- 题目要求第一个缺失的正整数,要求O(n)的时间复杂度,说明只能遍历有限次。
- 思路:遍历两次,第一次将所有正整数放到其正确的位置上,第二次返回值与其位置不一致的结果。
- 细节:遍历过程忽略非正和超过数组长度的值。
实现:
Java
实现见github。
3 Review
本周 review 的文章是 medium 上的The Simple Truth Behind Reading 200 Books a Year。
-
有人问巴菲特成功的秘诀,他说:每天阅读 500 页书籍。所有人都能做到,但是大部分人不会去做。
-
不要还未开始就放弃了。大部分听到“每天阅读500页”,第一反应就是:这不可能。然后开始为自己的反应编造理由:“我太忙了”,“我不够聪明”。请理智一点,放弃之前思考一下!
-
简单计算一下每年阅读一本书需要多少时间。根据统计数据美国人平均每分钟阅读200-400单词,一本非小说书籍平均50,000个词。结果是417小时(中文可能有差异,不过差别不会很大)。
|
|
-
寻找时间。我们可能会觉得417小时很多。但是据统计美国人每年平均在社交媒体上花费705小时,在电视上花费2737.5小时。如果把这些时间都拿来读书,那么每年可以读1600本书!我们需要做的就是分配一些时间在阅读上。
-
执行。知易行难。可以从以下几点执行:
- 改变环境,(1)移除环境中所有分散注意力的东西。(2)将书籍放在随手可得的地方。
- 养成习惯。意志力并不是改变生活方式的好手段,习惯才是。
- 使用多种媒介。开始时不要挑书,所有方面都阅读。不要局限于形式,你可以阅读纸质书,可以在手机上阅读,可以听有声书,可以在任何地方阅读。
心得: 放弃不切实际的幻想,行动起来,坚持下去,改变于微末之间。
4 Tip
go 中没有set
数据结构。虽然可以用map
来模拟,但是写法却不太直观。借助于 go 的类型定义,我们可以实现一个自己的set
类型。
|
|
使用Set32
非常简单,得益于 go 语言强大的类型设计。
5 Share
有时“少一点”工作可以产生更好的结果。这是一个关于效率的故事。
这次分享的内容来自 medium 的7 Things You Need To Stop Doing To Be More Productive, Backed By Science,讲述如何更有效率,我深有感触。
- 不要工作过长时间,提高你的效率。
- 不要经常说"yes"。把时间花在最值得的地方。
- 不要所有事情都自己做,让别人帮助你。不同的人有不同的视角,人多力量大。
- 放弃“完美主义”,过于执着完美会让你忽略全局,过于关注细节。
- 不要一直做重复的事情,让它自动化。
- 停止猜测,让数据来验证。
- 停下来,做一做其他的事情。这可能会让我们得到对长时间思考问题的“灵光一闪”。