# [165] Compare Version Numbers ## 題目資訊 - **難度**: Medium - **標籤**: Two Pointer, String - **題目連結**: https://leetcode.com/problems/compare-version-numbers/ - **練習日期**: 2025-09-23 - **目標複雜度**: 時間 O(n)、空間 O(1) ## 題目描述 Given two **version strings**, `version1` and `version2`, compare them. A version string consists of **revisions** separated by dots `'.'`. The **value of the revision** is its **integer conversion** ignoring leading zeros. To compare version strings, compare their revision values in **left-to-right order**. If one of the version strings has fewer revisions, treat the missing revision values as `0`. Return the following: If `version1 < version2`, return -1. If `version1 > version2`, return 1. Otherwise, return 0. ## 先備條件與限制 - 1 <= `version1.length, version2.length` <= 500 - version1 and version2 only contain digits and '.' - version1 and version2 are valid version numbers. - All the given revisions in `version1` and `version2` can be stored in a **32-bit integer** ## 解題思路 ### 初步分析 - 類型:字串雙指標掃描 - 關鍵觀察:版本號可以逐段比較,缺段視為 0,且修訂號只包含數字 - 複雜度目標理由:只需線性掃過兩個字串一次即可完成比較 ### 解法比較 1. 解法A(基準/暴力): - 名稱:`MyCompareVersion` - 思路:以 `Split('.')` 將版本字串拆成陣列,逐段轉成整數後比較;若另一側段數不足以 0 補齊 - 正確性:LeetCode 限制每段可裝進 32-bit 整數,直接使用 `int.TryParse` 安全可靠 - 複雜度:時間 O(n),空間 O(k)(k 為段數,需配置字串陣列與子字串) 2. 解法B(優化): - 名稱:`CompareVersion` - 思路:雙指標同步掃描兩個版本字串,藉由 `ReadOnlySpan` 抓取下一段,去除前導 0 後用字元比較避免溢位與額外配置 - 正確性:段長先比較、再逐字比較,完全符合題意;缺段會回傳空 span 視為 0 - 複雜度:時間 O(n),空間 O(1) ## 實作細節 ### 常見陷阱 - 前導 0:需在比較前移除,否則 `"01"` 與 `"1"` 會被視為不同 - 段數不一致:右側缺少的段要視為 0 - 空字串或末尾點:`""`、`"1."` 都可能出現,需要妥善處理 - 非數字字元:防守性處理(當前實作視為 0),但依題意實際資料不會出現 ## 測試案例 ### 範例輸入輸出 ``` Input: version1 = "1.2", version2 = "1.10" Output: -1 Explanation: version1's second revision is "2" and version2's second revision is "10": 2 < 10, so version1 < version2. ``` ### 邊界清單 - [x] 空字串 / 僅有 0 - [x] 單一段 / 全相同 - [x] 含 0 / 大數 / 前導 0 - [ ] 去重(與此題無關) - [x] 大資料壓力(長度 200 的版本字串) ## 複雜度分析 - 最壞:時間 O(n)、空間 O(1) - 備註:保留的 `MyCompareVersion` 雖然同為 O(n),但空間為 O(k) ## 相關題目 / Follow-up - 179. Largest Number:同樣涉及字串排序與比較 - 415. Add Strings:字串逐位操作 ## 學習筆記 - 今天學到:兩指標搭配 `ReadOnlySpan` 可以在 C# 中避免額外配置 - 卡住與修正:原本 console app 移除 `Main` 造成 `dotnet test` 無法編譯,後來補回精簡入口 - 待優化:若要支援超長版本段,可考慮使用 `BigInteger` 或自訂比較邏輯(目前已以字元比較處理) --- **總結**:核心在於逐段處理並正確處理前導 0 與缺段情況,適合練習字串雙指標與記憶體優化技巧。