iT邦幫忙

2026 iThome 鐵人賽

DAY 30
0
自我挑戰組

30天 LeetCode 演算法實戰:Java 與 Python 解法比較系列 第 30 篇

Day 30|30 天 LeetCode 學習總結:Java 與 Python 解法比較

  • 分享至 

  • xImage
  •  

這次的 30 天自主學習,我選擇以 LeetCode 作為主要練習平台,並使用 Java 和 Python 兩種程式語言進行實作。會選擇這個主題,是因為平常在學習程式設計時,常常知道基本語法要怎麼使用,但遇到實際問題時,卻不一定能馬上想到適合的解法。因此我希望透過每天完成一題 LeetCode,慢慢熟悉不同的資料結構與演算法,也藉由同一題使用 Java 和 Python 實作,觀察兩種語言在語法與使用方式上的差異。

在這 30 天裡,我從比較基礎的 Array、Hash Table 和 Stack 開始,接著學習 Two Pointers、Binary Search、Linked List,再慢慢接觸 Binary Tree、DFS、BFS、Sorting、Dynamic Programming、Backtracking、Heap 和 Sliding Window。剛開始遇到題目時,我常常會先想著「這題的程式碼到底要怎麼寫」,但練習幾天之後,我開始會先分析題目的條件,再思考需要記錄哪些資料,以及哪一種資料結構比較適合。這個轉變是我覺得自己在這 30 天裡比較明顯的進步。

其中讓我印象比較深刻的是 Linked List、Tree 和 Dynamic Programming。Linked List 一開始對我來說比較抽象,因為不像 Array 可以直接透過索引找到資料,需要透過 Node 一個一個連接起來。不過在練習 Reverse Linked List 和 Linked List Cycle 後,我開始比較能理解節點之間的關係。Tree 的 DFS 和 BFS 則讓我知道,同樣是一棵樹,可以使用不同的搜尋方式處理問題。DFS 比較著重於深入某一條路徑,而 BFS 則是按照層級逐步搜尋,實際寫過之後比單純看課本上的定義更容易理解。

Dynamic Programming 則是這次我覺得比較需要花時間理解的部分。像 Climbing Stairs、House Robber、Coin Change 和 Fibonacci Number,看起來是不同的題目,但實際練習後可以發現,它們都有將大問題拆成小問題,並利用之前計算過的結果來減少重複運算的概念。以前看到 DP 時,我比較容易覺得它是一個需要背起來的演算法,但經過這次練習後,我開始知道可以先找出問題之間的關係,再決定要怎麼保存之前的結果。

Day 23 到 Day 25 的 Backtracking 也讓我學到很多。Subsets、Permutations 和 Combination Sum 都需要透過遞迴去尋找不同的可能性,但三題的條件又不完全一樣。例如 Permutations 需要注意元素是否已經使用過,而 Combination Sum 則可以重複使用相同的數字。這讓我發現,即使幾道題目都屬於同一種演算法,也不能只記住一個固定模板,還是要先理解題目的條件,再調整自己的程式。

到了 Day 26 的 Heap、Day 27 的 Hash Table 加 Heap、Day 28 的 Sliding Window,以及 Day 29 的 LRU Cache,我開始感覺到前面學過的內容慢慢被串接起來。尤其 LRU Cache 同時使用 HashMap 和 Doubly Linked List,讓我第一次比較明顯地感受到不同資料結構可以互相搭配。HashMap 負責快速找到資料,而 Linked List 則負責維護資料的使用順序。這也讓我理解,實際解決問題時,不一定只需要使用一種資料結構,而是可以根據需求組合不同的方法。

除了演算法之外,這次我也特別比較了 Java 和 Python。實際寫過相同題目後,我發現 Python 的語法通常比較簡潔,例如建立 Dictionary、List 或操作 Heap 時,需要寫的程式碼相對少一些,因此在 LeetCode 上寫題目時,可以比較快速地完成。但是 Java 的型別與結構比較明確,需要宣告資料型別,也常常需要建立 Class 或使用較完整的語法。雖然一開始會覺得 Java 比較繁瑣,但實際使用之後也能感受到它在資料型別與程式結構上的清楚程度。

我覺得使用兩種語言解同一題,最大的好處是可以讓我把「語法」和「解題邏輯」分開來思考。當 Java 和 Python 的程式碼長得完全不一樣時,我還是需要確認兩份程式是否使用相同的演算法。這讓我慢慢發現,真正重要的不是記住某一段程式碼,而是理解這段程式碼為什麼這樣寫。如果知道解題邏輯,即使換成另一種程式語言,也比較有機會重新寫出來。

這 30 天也讓我開始注意時間複雜度和空間複雜度。以前看到 O(n)、O(log n) 或 O(n²) 時,可能只覺得是課堂上需要記住的內容,但實際解題後,我開始理解 Big-O 是用來分析程式效率的方式。例如 Binary Search 可以透過每次縮小一半的搜尋範圍來達到 O(log n),而 Hash Table 可以在平均情況下快速找到資料。當資料量越來越大時,選擇不同的演算法可能會造成很大的差異,因此效率也變成我寫程式時會開始思考的事情。

當然,這 30 天並不是每天都很順利。有些題目第一次看到時,我甚至不知道應該從哪裡開始,也會遇到程式碼寫出來卻沒有得到正確結果的情況。有時候只是很小的一個條件,就可能讓整個結果不同。以前遇到這種狀況時,我容易覺得自己是不是不適合寫程式,但這次每天固定練習之後,我比較能接受「不會」其實是學習過程的一部分。與其一直卡在不知道答案,我開始學著把題目拆小,一步一步確認自己的想法,再找出是哪個地方出了問題。

完成這 30 天後,我覺得自己最大的收穫並不是記住了多少題 LeetCode,而是開始建立一套面對問題的思考方式。現在看到題目時,我會開始思考它是不是適合使用 Hash Table、Stack、Linked List、Tree、Heap 或 Sliding Window,也會注意是否可以透過 DFS、BFS、Dynamic Programming 或 Backtracking 來解決。雖然目前還沒有辦法看到每一題就立刻想到最佳解法,但至少不像一開始一樣完全沒有方向。

這次自主學習也讓我發現,程式設計並不是單純把語法背起來就可以,而是需要不斷練習如何分析問題。30 天的時間並不長,我也還有很多資料結構和演算法沒有接觸過,但這次的練習讓我對自己的程式設計基礎有了更完整的認識。從一開始需要慢慢理解每一道題目,到最後可以把不同的資料結構和演算法組合起來,我覺得這就是這次自主學習最有價值的地方。

最後,這 30 天對我來說比較像是一個起點,而不是終點。透過 Java 和 Python 的雙語實作,我除了練習程式語言,也開始學習如何分析問題、選擇資料結構、思考演算法以及判斷程式效率。未來如果還有機會繼續練習,我希望可以慢慢挑戰難度更高的題目,讓自己不只是「把程式寫出來」,而是能夠真正理解為什麼這樣設計,以及有沒有更好的解法。

30 天的 LeetCode 練習到這裡告一段落,但這次學到的解題思維,會成為之後繼續學習程式設計的基礎。


上一篇
Day 29|LRU Cache:Java 與 Python 實作 HashMap + Linked List
系列文
30天 LeetCode 演算法實戰:Java 與 Python 解法比較 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言