4,449 人赞同了该回答
先贴一个自己的刷题的进度吧:

到目前为止,一共刷了 428 题。
通过刷题,拿了很多公司(IBM, Google, Amazon, Microsoft, Zenefits, Splunk)的面试以及 offer。这 428 题不是简单的刷一遍就过去的,而是反复练习,直到代码最优,解法最优(有时候甚至觉得自己的代码精简到一个符号都无法减少的地步)。所以有时候面试官问问题,问题还没说完,我就知道应该如何表述自己的心路历程,然后慢慢地给出最优解。
而这一切的关键就在于:做笔记!
下面是我的笔记截图:

对于遇到的每个题目,事后我都做上标记:普通题目,难题、好题。此外,每个题目都分为以下几个步骤做好详细的笔记:
- 原题目
- 自己的第一遍解法
- 网上好的解法
- 自己可以改进的地方
- 进一步精简优化自己的代码直至代码简无可简(这是非常关键的一步,到达这一步,才会发现获得能力的提升远远要超过简单地把题目解出来)
- 获得的思考(或者学习到的地方,可以是算法、数据结构或者 Java 的特性—例如 Stream 等等)
每一个题目都经过至少一遍这样的迭代。这样几遍下来,我对于每个题目都有了更加深刻的理解,大部分的题目我都有自信能够写出最优解甚至代码都是最优化的(至少比论坛回复里面的最高票答案还要精简)。
举个例子,Two Sum问题。
我最早的解法是暴力搜索。当时的代码 (C++) 是这样的:
class Solution {public:vector<int> twoSum(vector<int> &numbers, int target) {// Start typing your C/C++ solution below// DO NOT write int main() functionvector<int> index(2, 0);if (numbers.empty() || numbers.size() == 1)return index;for (int i = 0; i < numbers.size()-1; ++i) {// j should start from i+1for (int j = i+1; j < numbers.size(); ++j) {if (numbers[i] + numbers[j] == target) {index.clear();index.push_back(i+1);index.push_back(j+1);break;}}}return index;}}
这个解法不仅复杂度高,而且代码冗长繁琐。
后来看了网上高票答案的解法,知道了用 hashmap 来做,于是写出了优化的代码 (Java):
public int[] twoSum(int[] nums, int target) {Map<Integer, Integer> map = new HashMap<>();int[] result = {-1, -1};for (int i = 0; i < nums.length; ++i) {if (map.containsKey(target - nums[i])) {result[0] = map.get(target - nums[i]);result[1] = i;break;}map.put(nums[i], i);}return result;}
再后来,对代码进行了一些细节的简化:
public class Solution {
public int[] twoSum(int[] nums, int target) {
Map<Integer, Integer> map = new HashMap();
for (int i = 0; i < nums.length; ++i) {
if (map.containsKey(target- nums[i])) {
return new int[]{map.get(target- nums[i]), i};
}
map.put(nums[i], i);
}
return int[]{-1, -1};
}
}
至此,代码几乎达到最精简状态。(中间有略去几次迭代)总之,不断地学习别人的代码,改进自己的代码,不断地锤炼自己的代码,直至算法最优化,代码最简洁!潜移默化中,不仅对题目解法有了更深刻的理解(什么是最优解),而且也知道如何用最简洁的代码实现这个最优解。
再举个极端的例子吧,179. Largest Number,这个题目我最后精简成的代码如下:
public String largestNumber(int[] nums) {
return Arrays.stream(nums)
.mapToObj(String::valueOf)
.sorted((s1, s2) -> (s2 + s1).compareTo(s1 + s2))
.reduce((s1, s2) -> s1.equals("0") ? s2 : s1 + s2).get();
}
我本人不是算法高手,算是勤能补拙类型。这样长期坚持下来,慢慢地感觉自己编程能力提升了很多。不仅面试的时候得心应手,而且在工作中提交 code review 的时候,往往有自信说自己的代码是简单,干净与优雅的。
赞同 4449198 条评论
