對於遇到的每一個題目,過後都作上標記:普通題目,難題、好題。此外,每一個題目都分爲如下幾個步驟作好詳細的筆記:面試
每個題目都通過至少一遍這樣的迭代。這樣幾遍下來,我對於每一個題目都有了更加深入的理解,大部分的題目我都有自信可以寫出最優解甚至代碼都是最優化的(至少比論壇回覆裏面的最高票答案還要精簡)。算法
舉個例子,兩數之和問題。編程
我最先的解法是暴力搜索。當時的代碼(Java)是這樣的:數據結構
class Solution { public int[] twoSum(int[] nums, int target) { for (int i = 0; i < nums.length; i++) { for (int j = i+1; j < nums.length; j++) { if (nums[j] == target - nums[i]) { return new int[]{i, j}; } } } throw new IllegalArgumentException("No two sum solution"); } }
這個解法不只複雜度高,並且代碼冗長繁瑣。學習
後來看了網上高票答案的解法,知道了用hashmap來作,因而寫出了優化的代碼(Java):優化
class Solution { public int[] twoSum(int[] nums, int target) { HashMap<Integer,Integer> map = new HashMap<>(); int[] res = new int[2]; for (int i = 0; i < nums.length; i++) { int dif = target - nums[i]; if (map.get(dif) != null) { res[0] = map.get(dif); res[1] = i; return res; } map.put(nums[i],i); } return res; } }
再後來,對代碼進行了一些細節的簡化:spa
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 new int[]{-1, -1}; } }
至此,代碼幾乎達到最精簡狀態。(中間有略去幾回迭代)總之,不斷地學習別人的代碼,改進本身的代碼,不斷地錘鍊本身的代碼,直至算法最優化,代碼最簡潔!code
潛移默化中,不只對題目解法有了更深入的理解(什麼是最優解),並且也知道如何用最簡潔的代碼實現這個最優解。blog
再舉個極端的例子吧,179. 最大數,這個題目我最後精簡成的代碼以下:get
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的時候,每每有自信說本身的代碼是簡單,乾淨與優雅的。