LeetCode 165. 比較版本號 - 優雅Java解決方案

文章目錄

  • LeetCode 165. 比較版本號 - 優雅Java解決方案
    • 題目描述
    • 示例分析
      • 示例 1
      • 示例 2
      • 示例 3
    • 算法思路
    • Java實現方案
      • 方案一:雙指針法(推薦)
      • 方案二:優化的單次遍歷法
    • 可視化執行過程
      • 示例:compareVersion("1.2", "1.10")
      • 示例:compareVersion("1.01", "1.001")
      • 示例:compareVersion("1.0", "1.0.0.0")
    • 算法復雜度分析
      • 時間復雜度:O(max(m, n))
      • 空間復雜度:
    • 測試用例
    • 關鍵要點總結

LeetCode 165. 比較版本號 - 優雅Java解決方案

題目描述

給你兩個 版本號字符串 version1version2 ,請你比較它們。版本號由被點 ‘.’ 分開的修訂號組成。修訂號的值是它轉換為整數并忽略前導零。

比較版本號時,請按從左到右的順序依次比較它們的修訂號。如果其中一個版本字符串的修訂號較少,則將缺失的修訂號視為 0。

返回規則:

  • 如果 version1 < version2 返回 -1
  • 如果 version1 > version2 返回 1
  • 除此之外返回 0

示例分析

示例 1

輸入:version1 = "1.2", version2 = "1.10"
輸出:-1
解釋:version1 的第二個修訂號為 "2",version2 的第二個修訂號為 "10":2 < 10,所以 version1 < version2

示例 2

輸入:version1 = "1.01", version2 = "1.001"
輸出:0
解釋:忽略前導零,"01" 和 "001" 都代表相同的整數 "1"

示例 3

輸入:version1 = "1.0", version2 = "1.0.0.0"
輸出:0
解釋:version1 有更少的修訂號,每個缺失的修訂號按 "0" 處理

算法思路

  1. 分割版本號:使用點號分割版本號字符串
  2. 雙指針遍歷:使用兩個指針分別遍歷兩個版本號的修訂號數組
  3. 逐個比較:從左到右比較對應位置的修訂號
  4. 處理邊界:當某個版本號的修訂號用完時,將其視為0
  5. 返回結果:根據比較結果返回相應值

Java實現方案

方案一:雙指針法(推薦)

public class Solution {public int compareVersion(String version1, String version2) {String[] v1 = version1.split("\\.");String[] v2 = version2.split("\\.");int maxLength = Math.max(v1.length, v2.length);for (int i = 0; i < maxLength; i++) {int num1 = i < v1.length ? Integer.parseInt(v1[i]) : 0;int num2 = i < v2.length ? Integer.parseInt(v2[i]) : 0;if (num1 < num2) {return -1;} else if (num1 > num2) {return 1;}}return 0;}
}

方案二:優化的單次遍歷法

public class Solution {public int compareVersion(String version1, String version2) {int i = 0, j = 0;int n1 = version1.length(), n2 = version2.length();while (i < n1 || j < n2) {int num1 = 0, num2 = 0;// 解析version1的當前修訂號while (i < n1 && version1.charAt(i) != '.') {num1 = num1 * 10 + (version1.charAt(i) - '0');i++;}i++; // 跳過點號// 解析version2的當前修訂號while (j < n2 && version2.charAt(j) != '.') {num2 = num2 * 10 + (version2.charAt(j) - '0');j++;}j++; // 跳過點號if (num1 < num2) {return -1;} else if (num1 > num2) {return 1;}}return 0;}
}

可視化執行過程

讓我們通過示例來可視化算法的執行過程:

示例:compareVersion(“1.2”, “1.10”)

初始狀態:
version1 = "1.2"    →  ["1", "2"]
version2 = "1.10"   →  ["1", "10"]第1輪比較:
位置 i=0: num1=1, num2=1
1 == 1  →  繼續第2輪比較:
位置 i=1: num1=2, num2=10  
2 < 10  →  返回 -1結果: -1 (version1 < version2)

示例:compareVersion(“1.01”, “1.001”)

初始狀態:
version1 = "1.01"   →  ["1", "01"]   →  [1, 1]
version2 = "1.001"  →  ["1", "001"]  →  [1, 1]第1輪比較:
位置 i=0: num1=1, num2=1
1 == 1  →  繼續第2輪比較:
位置 i=1: num1=1, num2=1 (忽略前導零)
1 == 1  →  繼續所有修訂號都相等
結果: 0 (version1 == version2)

示例:compareVersion(“1.0”, “1.0.0.0”)

初始狀態:
version1 = "1.0"      →  ["1", "0"]
version2 = "1.0.0.0"  →  ["1", "0", "0", "0"]第1輪比較:
位置 i=0: num1=1, num2=1
1 == 1  →  繼續第2輪比較:
位置 i=1: num1=0, num2=0
0 == 0  →  繼續第3輪比較:
位置 i=2: num1=0(缺失視為0), num2=0
0 == 0  →  繼續第4輪比較:
位置 i=3: num1=0(缺失視為0), num2=0
0 == 0  →  繼續所有修訂號都相等
結果: 0 (version1 == version2)

算法復雜度分析

時間復雜度:O(max(m, n))

  • m 和 n 分別是兩個版本號的修訂號個數
  • 需要遍歷較長版本號的所有修訂號

空間復雜度:

  • 方案一:O(m + n) - 需要存儲分割后的數組
  • 方案二:O(1) - 只使用常數額外空間

測試用例

public class TestCompareVersion {public static void main(String[] args) {Solution solution = new Solution();// 測試用例1System.out.println(solution.compareVersion("1.2", "1.10"));      // -1// 測試用例2  System.out.println(solution.compareVersion("1.01", "1.001"));    // 0// 測試用例3System.out.println(solution.compareVersion("1.0", "1.0.0.0"));   // 0// 邊界測試System.out.println(solution.compareVersion("0.1", "1.1"));       // -1System.out.println(solution.compareVersion("1.0.1", "1"));       // 1System.out.println(solution.compareVersion("7.5.2.4", "7.5.3")); // -1}
}

關鍵要點總結

  1. 忽略前導零:使用 Integer.parseInt() 自動處理
  2. 處理不同長度:缺失的修訂號視為0
  3. 效率優化:方案二避免了字符串分割的開銷
  4. 邊界處理:正確處理版本號末尾的點號和空修訂號

這個解決方案具有良好的可讀性和效率,能夠正確處理所有邊界情況。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/97643.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/97643.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/97643.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于Kubernetes StatefulSet的有狀態微服務部署與持久化存儲實踐經驗分享

基于Kubernetes StatefulSet的有狀態微服務部署與持久化存儲實踐經驗分享 在傳統微服務架構中&#xff0c;大多數服務都是無狀態的&#xff08;Stateless&#xff09;&#xff0c;可以通過 Deployment、ReplicaSet 等控制器實現水平自動擴縮容。但在生產環境中&#xff0c;仍有…

MySQL編程開發

變量系統變量&#xff1a;MySQL內置變量#查看所有系統變量show variables \G;#通過模糊查詢篩選變量show variables like “%path%”;全局變量&#xff1a;在所有終端中都生效&#xff1b;會話變量&#xff1a;在當前會話&#xff08;本次登錄&#xff09;&#xff1b;#可以通過…

20250830_Oracle 19c CDB+PDB(QMS)默認表空間、臨時表空間、歸檔日志、閃回恢復區巡檢手冊

PDB 關業務,CDB 管底層;每天緊盯 PDB,必要時看 CDB。 一、CDB 與 PDB 的關系 Oracle 12c 以后引入 多租戶架構(Multitenant),分成兩類容器: 層級 名稱 作用 存儲內容 典型操作 CDB CDB$ROOT(容器數據庫) 數據庫實例的根容器 Oracle 元數據、系統表字典、公共用戶、PDB…

什么是MIPS架構?RISC-V架構?有什么區別?【超詳細初學者教程】

什么是MIPS架構&#xff1f;RISC-V架構&#xff1f;有什么區別&#xff1f;【超詳細初學者教程】 關鍵詞&#xff1a;MIPS架構&#xff0c;RISC-V架構&#xff0c;精簡指令集RISC&#xff0c;嵌入式系統&#xff0c;CPU架構對比&#xff0c;指令集架構&#xff0c;開源處理器&…

IDEA Spring屬性注解依賴注入的警告 Field injection is not recommended 異常解決方案

一、異常錯誤 在使用 IntelliJ IDEA 進行 Spring 開發時&#xff0c;當使用 Autowired 注解直接在字段上進行依賴注入時&#xff0c;IDE 會顯示黃色警告&#xff1a; Field injection is not recommended這個警告出現在以下代碼模式中&#xff1a; Service public class UserSe…

智能核心:機器人芯片的科技革新與未來挑戰

在人工智能與機器人技術深度融合的今天&#xff0c;機器人芯片作為驅動智能機器的“大腦”&#xff0c;正成為科技競爭的戰略制高點。這一微小卻至關重要的硬件&#xff0c;決定了機器人的計算能力、響應速度與智能水平&#xff0c;是機器人從“自動化”邁向“自主化”的關鍵所…

經典掃雷游戲實現:從零構建HTML5掃雷游戲

一、引言 掃雷是一款經典的單人益智游戲&#xff0c;起源于20世紀60年代&#xff0c;并在90年代隨著Windows操作系統的普及而風靡全球。本文將詳細介紹如何使用現代網頁技術&#xff08;HTML、CSS和JavaScript&#xff09;從零開始構建一個功能完整的掃雷游戲。我們將涵蓋游戲邏…

ccache編譯加速配置

ccache 介紹 ccache(“compiler cache”的縮寫)是一個編譯器緩存,該工具會高速緩存編譯生成的信息,并在編譯的特定部分使用高速緩存的信息, 比如頭文件,這樣就節省了通常使用 cpp 解析這些信息所需要的時間。 github :https://github.com/ccache/ccache home:https://c…

數據庫主鍵選擇策略分析

為什么不推薦使用數據庫自增主鍵&#xff1f;分庫分表問題&#xff1a;自增ID在分庫分表場景下會導致ID沖突需要額外機制(如步長設置)來保證全局唯一&#xff0c;增加系統復雜度安全性問題&#xff1a;自增ID容易暴露業務量(如訂單號連續)可能被惡意爬取數據分布式系統限制&…

線性代數理論——狀態空間的相關概念以及由系統的輸入輸出導出狀態空間描述

線性代數理論——狀態空間 狀態&#xff1a;動態系統的狀態就是指系統的過去、現在、將來的運動狀況&#xff0c;精確的說就是狀態需要一組必要而充分的數據來表明。 狀態變量&#xff1a;可以表達系統運動狀態的變量都是狀態變量。 狀態變量組&#xff1a;可以完全表征系統在時…

【GaussDB】排查應用高可用切換出現數據庫整體卡頓及報錯自治事務無法創建的問題

【GaussDB】排查應用高可用切換出現數據庫整體卡頓及報錯自治事務無法創建的問題 背景 某客戶在做應用程序的高可用切換測試&#xff0c;在應用程序中&#xff0c;收到了來自數據庫的報錯&#xff0c;不能創建自治事務 ERROR: autonomous transaction failed to create auton…

shell腳本第五階段---shell函數與正則表達式

學習目標掌握case語句的基本語法結構掌握函數的定義以及調用掌握常用的正則表達式元字符含義一、case語句case語句為多選擇語句。可以用case語句匹配一個值與一個模式&#xff0c;如果匹配成功&#xff0c;執行相匹配的命令。case var in 定義變量&#xff1b;var代表變量名…

164.在 Vue3 中使用 OpenLayers 加載 Esri 地圖(多種形式)

適配&#xff1a;Vue 3 Vite TypeScript&#xff08;也兼容 JS&#xff09; 地圖引擎&#xff1a;OpenLayers v10 目標&#xff1a;一次性學會 多種 Esri 底圖加載方式、注記疊加、動態切換、令牌&#xff08;Token&#xff09;鑒權、常見坑位排查。一、效果預覽二、為什么選…

深入了解Flink核心:Slot資源管理機制

TaskExecutor、Task 和 Slot 簡單來說&#xff0c;它們的關系可以比作&#xff1a;TaskExecutor&#xff1a;一個工廠&#xff0c;擁有固定的生產資源。TaskSlot&#xff1a;工廠里的一個工位。每個工位都預先分配了一份獨立的資源&#xff08;主要是內存&#xff09;。Task&am…

java web 練習demo。生成簡單驗證碼前端是jsp

目錄結構 demo\ ├── WEB-INF\ │ └── weblogic.xml # WebLogic服務器配置文件 ├── demo.iml # IntelliJ IDEA項目配置文件 ├── lib\ # Java EE核心依賴庫 │ ├── javax.annotation.jar │ ├── javax.ejb.jar │ ├── javax.…

擁抱智能高效翻譯 ——8 款視頻翻譯工具深度測評

前陣子幫知識博主做跨境視頻翻譯&#xff0c;踩了不少坑&#xff1a;把 “內卷” 直譯成 “involution” 讓海外觀眾困惑&#xff0c;多語種版本趕工 3 天只出 2 種&#xff0c;還得手動核對 “碳中和”“非遺” 這類特色詞的譯法&#xff1b;用傳統工具譯完&#xff0c;視頻要…

[知識點記錄]SQLite 數據庫和MySQL 數據庫有什么區別?

核心區別&#xff1a;一個“內嵌”&#xff0c;一個“獨立”SQLite (你的個人筆記本)本質&#xff1a; 它是“無服務器”的&#xff0c;或者叫“內嵌式”數據庫。它不需要一個獨立的程序一直在后臺運行。你的應用程序&#xff08;比如Strapi&#xff09;直接就能讀寫它的數據庫…

【Spark Core】(二)RDD編程入門

目錄1 程序入口&#xff1a;SparkContext對象2 RDD的創建2.1 本地創建2.2 讀取文件創建3 RDD算子4 常用Transform算子4.1 map算子4.2 flatMap算子4.3 reduceBykey算子4.4 mapValues算子<實例> WordCount4.5 groupBy算子4.6 filter算子4.7 distinct算子4.8 union算子4.9 j…

java IDEA run/Debug異常:“jdk1.8injava.exe“ CreateProcess error=206, 文件名或擴展名太長

&#x1f9d1; 博主簡介&#xff1a;CSDN博客專家、CSDN平臺優質創作者&#xff0c;高級開發工程師&#xff0c;數學專業&#xff0c;10年以上C/C, C#,Java等多種編程語言開發經驗&#xff0c;擁有高級工程師證書&#xff1b;擅長C/C、C#等開發語言&#xff0c;熟悉Java常用開發…

Java 函數編程之【過濾器filter()合并】【predicate(斷言)】與【謂詞邏輯】

Java函數式編程之【過濾器filter合并】【predicate&#xff08;斷言&#xff09;】與【謂詞邏輯】一、合并多個過濾器filter &#xff08;Lambda版本&#xff09;二、合并多個過濾器filter &#xff08;謂詞邏輯&#xff08;Predicate&#xff09;版本&#xff09;&#xff08;…