為什麼要重視演算法
面試畢竟歷程- 其實這是個偽命題,如果為了面試,大家去背一下特定的幾個演算法答案就好了
- 提高邏輯思維,理解能力
- 提高程式碼質量
為什麼說演算法是程式設計師最應該學習的技能,沒有之一
為什麼這麼說呢?可以思考一下
學框架其實就是學怎麼更好的用人家封裝好的api
看原始碼,就是看人家怎麼實現的這個元件,學習人家的設計思維。
但真的是這樣嗎?但其實大多數情況都是為了應付面試,然後實際學習場景大家都是看看別人的部落格,看看講解視訊,然後隨便扒扒原始碼
綜上所述其實,無論學習新框架還是看原始碼,更多的考驗的是記憶力,與略微的理解能力
思考一下,為什麼面試都要考演算法?
其實我們都在逃避,相比於演算法,其他的能力確實相對於來說比較容易掌握
- 程式設計師更重要的就是邏輯能力,服務端更甚
-
優秀的軟體工程師必須具備過硬的程式碼開發能力,而這就體現在你對資料結構、演算法思維、程式碼效率優化等知識的儲備上,並直接反應在你工作中解決實際問題的好壞上。
能力分佈表
邏輯能力 | 理解能力 | 記憶力 | |
---|---|---|---|
演算法 | 60% | 30% | 10% |
新框架,新知識 | 10% | 20% | 70% |
原始碼探索 | 20% | 30% | 50% |
為什麼說演算法會提高程式碼質量
舉個簡單的例子
在海量資料中查詢指定資料,粗笨的方法就是迴圈便利一邊找到對應的就好了,
如何用演算法來解決?
- 有序儲存
- 二分查詢
收益:資料量小的時候可能沒什麼明顯收益,但假如我們資料量達到了1000w,兩種查詢方法的效率可能就是1000萬次和24次的區別了(log2 10000000 = 23.25)
程式碼質量如何一步步提高
- 暴力解法
- 在沒有任何時間、空間約束下,完成程式碼任務的開發。
- 剔除無效操作處理
- 將程式碼中的無效計算、無效儲存剔除,降低時間或空間複雜度。
- 時空轉換
- 設計合理資料結構,完成時間複雜度向空間複雜度的轉移。
- 邏輯歸納
- 利用邏輯關係,完成時間複雜度和空間複雜度的降低
eg1:
假設有任意多張面額為 2 元、3 元、7 元的貨幣,現要用它們湊出 100 元,求總共有多少種可能性
暴力解法
public void s1_1() { int count = 0; for (int i = 0; i <= (100 / 7); i++) { for (int j = 0; j <= (100 / 3); j++) { for (int k = 0; k <= (100 / 2); k++) { if (i * 7 + j * 3 + k * 2 == 100) { count += 1; } } } } System.out.println(count); }
3 層的 for 迴圈。從結構上來看,顯然的 O( n³ ) 的時間複雜度。思考一下會發現,最內層的 for 是多餘的剔除無效操作處理
public void s1_2() { int count = 0; for (int i = 0; i <= (100 / 7); i++) { for (int j = 0; j <= (100 / 3); j++) { if ((100-i*7-j*3 >= 0)&&((100-i*7-j*3) % 2 == 0)) { count += 1; } } } System.out.println(count); }
eg2:
給定一個整數陣列 nums
和一個整數目標值 target
,請你在該陣列中找出 和為目標值 的那 兩個 整數,並返回它們的陣列下標。
暴力解法
public int[] s2_1(int[] nums, int target) { int n = nums.length; for (int i = 0; i < n; ++i) { for (int j = i + 1; j < n; ++j) { if (nums[i] + nums[j] == target) { return new int[]{i, j}; } } } return new int[0]; }
時空轉換
public int[] s2_2(int[] nums, int target) { Map<Integer, Integer> hashtable = new HashMap<Integer, Integer>(); for (int i = 0; i < nums.length; ++i) { if (hashtable.containsKey(target - nums[i])) { return new int[]{hashtable.get(target - nums[i]), i}; } hashtable.put(nums[i], i); } return new int[0]; }