LeetCode
做筆記
對于遇到的每個題目,事后都做上標記:普通題目,難題、好題,此外,每個題目都分為以下幾個步驟做好詳細的筆記:
1. 原題目
2. 自己的第一遍解法
3. 網上好的解法
4. 自己可以改進的地方
5. 進一步精簡優化自己的代碼直至代碼簡無可簡(這是非常關鍵的一步,到達這一步,才會發現獲得能力的提升遠遠要超過簡單地把題目解出來)
6. 獲得的思考(或者學習到的地方,可以是演算法、資料結構或者Java的特性—例如Stream等等)
每一個題目都經過至少一遍這樣的迭代,這樣幾遍下來,我對于每個題目都有了更加深刻的理解,大部分的題目我都有自信能夠寫出最優解甚至代碼都是最優化的(至少比論壇回復里面的最高票答案還要精簡),
舉個例子,兩數之和問題,
我最早的解法是暴力搜索,當時的代碼(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;
}
}
再后來,對代碼進行了一些細節的簡化:
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};
}
}
至此,代碼幾乎達到最精簡狀態,(中間有略去幾次迭代)總之,不斷地學習別人的代碼,改進自己的代碼,不斷地錘煉自己的代碼,直至演算法最優化,代碼最簡潔!
潛移默化中,不僅對題目解法有了更深刻的理解(什么是最優解),而且也知道如何用最簡潔的代碼實作這個最優解,
再舉個極端的例子吧,179. 最大數,這個題目我最后精簡成的代碼如下:
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的時候,往往有自信說自己的代碼是簡單,干凈與優雅的,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/117868.html
標籤:其他
上一篇:CodeForces - 1230D(思維+位運算)
下一篇:查找演算法
