據(jù)結(jié)構(gòu)實(shí)戰(zhàn):從復(fù)數(shù)集合題解析優(yōu)先隊(duì)列與TreeSet應(yīng)用)
1. 項(xiàng)目概述從一道復(fù)試上機(jī)題看數(shù)據(jù)結(jié)構(gòu)的實(shí)戰(zhàn)應(yīng)用最近在幫幾個(gè)準(zhǔn)備考研復(fù)試的同學(xué)梳理編程題發(fā)現(xiàn)“復(fù)數(shù)集合”這道題出現(xiàn)的頻率相當(dāng)高。這不僅是北京郵電大學(xué)計(jì)算機(jī)專(zhuān)業(yè)復(fù)試上機(jī)中的一道經(jīng)典題目也頻繁出現(xiàn)在其他高校的機(jī)試環(huán)節(jié)中。乍一看題目要求實(shí)現(xiàn)一個(gè)復(fù)數(shù)集合支持插入、刪除和查詢操作似乎平平無(wú)奇。但真正上手實(shí)現(xiàn)尤其是要在有限時(shí)間內(nèi)寫(xiě)出健壯、高效的代碼就會(huì)發(fā)現(xiàn)里面藏著不少“坑”非??简?yàn)對(duì)數(shù)據(jù)結(jié)構(gòu)基礎(chǔ)、面向?qū)ο笤O(shè)計(jì)以及邊界條件處理的綜合能力。這道題的核心價(jià)值在于它用一個(gè)非常具體的數(shù)學(xué)對(duì)象——復(fù)數(shù)包裝了對(duì)“優(yōu)先隊(duì)列”或“有序集合”這一經(jīng)典數(shù)據(jù)結(jié)構(gòu)及其操作的理解。你不僅要能存儲(chǔ)和管理數(shù)據(jù)還要能根據(jù)特定的規(guī)則比如復(fù)數(shù)模的大小進(jìn)行動(dòng)態(tài)排序和選擇性的輸出。這恰恰是許多實(shí)際應(yīng)用場(chǎng)景的縮影比如游戲中的怪物刷新系統(tǒng)按優(yōu)先級(jí)或距離刷新、任務(wù)調(diào)度中心按緊急程度或截止時(shí)間調(diào)度等。通過(guò)這道題我們可以深入探討如何根據(jù)需求選擇最合適的數(shù)據(jù)結(jié)構(gòu)并優(yōu)雅地處理各種異常情況。接下來(lái)我將以一個(gè)從業(yè)者的視角拆解這道題的多種解法、背后的設(shè)計(jì)權(quán)衡以及那些教科書(shū)上不會(huì)寫(xiě)的調(diào)試心得和性能優(yōu)化技巧。2. 題目需求深度解析與設(shè)計(jì)思路拆解2.1 問(wèn)題定義與輸入輸出規(guī)格我們先來(lái)明確一下這道題通常的表述。題目要求模擬一個(gè)復(fù)數(shù)集合Complex Set并處理一系列命令。每個(gè)復(fù)數(shù)由實(shí)部Real和虛部Imaginary構(gòu)成表示為(a, bi)或abi的形式。常見(jiàn)的操作命令包括Insert abi: 向集合中插入一個(gè)復(fù)數(shù)abi。如果集合中已存在實(shí)部和虛部完全相同的復(fù)數(shù)則忽略此次插入或根據(jù)題目要求處理通常是不重復(fù)插入。?Pop: 從集合中移除并輸出“模最大”的那個(gè)復(fù)數(shù)。復(fù)數(shù)的模Magnitude計(jì)算公式為sqrt(a^2 b^2)。如果存在多個(gè)復(fù)數(shù)模相同則輸出其中“字典序最小”的一個(gè)。通常定義字典序?yàn)橄缺容^實(shí)部實(shí)部相同再比較虛部。如果集合為空則輸出“empty”。?Size: 查詢并輸出當(dāng)前集合中復(fù)數(shù)的個(gè)數(shù)。輸入是一系列按行給出的命令以某條特定命令如“End”結(jié)束。輸出是對(duì)應(yīng)每條Pop和Size命令的結(jié)果。關(guān)鍵點(diǎn)與陷阱分析模的計(jì)算與比較比較模的大小通常不需要真的開(kāi)平方根計(jì)算sqrt(a^2b^2)直接比較a^2 b^2的值即可以避免浮點(diǎn)數(shù)精度問(wèn)題。這是第一個(gè)優(yōu)化點(diǎn)。“字典序”的定義這是容易混淆的地方。當(dāng)模相等時(shí)如何定義“最小”常見(jiàn)且合理的定義是先比較實(shí)部aa小的更小如果a相等則比較虛部bb小的更小。這需要我們?cè)谧远x比較邏輯時(shí)精確實(shí)現(xiàn)。重復(fù)元素的處理題目是否要求集合元素唯一從“集合”的數(shù)學(xué)定義和常見(jiàn)實(shí)現(xiàn)來(lái)看通常要求元素唯一。這意味著在Insert時(shí)需要判斷是否已存在??占咸幚韴?zhí)行Pop時(shí)如果集合為空必須進(jìn)行防御性編程輸出特定信息而不是崩潰。2.2 核心數(shù)據(jù)結(jié)構(gòu)選型與權(quán)衡這是本題最核心的部分不同的數(shù)據(jù)結(jié)構(gòu)選擇直接決定了代碼的復(fù)雜度、效率和實(shí)現(xiàn)的優(yōu)雅程度。方案一使用有序數(shù)據(jù)結(jié)構(gòu)如TreeSet/PriorityQueue這是最直觀和高效的方案。我們需要一個(gè)能自動(dòng)根據(jù)復(fù)數(shù)“優(yōu)先級(jí)”先按模降序模相同按字典序升序進(jìn)行排序的集合。PriorityQueue最大堆在Java中我們可以自定義一個(gè)比較器ComparatorComplex。注意為了每次Pop都能拿到“模最大”的我們需要一個(gè)最大堆。但Java的PriorityQueue默認(rèn)是最小堆。因此比較器的邏輯需要反過(guò)來(lái)寫(xiě)比較兩個(gè)復(fù)數(shù)c1和c2。計(jì)算mod1 c1.a*c1.a c1.b*c1.bmod2 c2.a*c2.a c2.b*c2.b。如果mod1 ! mod2 則返回mod2 - mod1這樣模大的會(huì)被認(rèn)為“更小”從而排在堆頂。如果mod1 mod2 則按字典序比較先比a 若a1 ! a2 返回a1 - a2字典序小的實(shí)部更小但我們這里需要字典序小的在模相同時(shí)優(yōu)先級(jí)更高這里要小心。實(shí)際上對(duì)于最大堆我們希望模最大的在堆頂模相同時(shí)字典序最小的在堆頂。所以當(dāng)模相等時(shí)比較邏輯應(yīng)為若a1 ! a2 返回a1 - a2否則返回b1 - b2。這樣字典序越小的復(fù)數(shù)其比較值越小在最大堆里優(yōu)先級(jí)就越高因?yàn)槎秧斒恰白钚 痹剡@里“最小”指比較器的返回值最小。這里極易出錯(cuò)需要仔細(xì)推導(dǎo)。TreeSetTreeSet是基于紅黑樹(shù)的有序集合它要求元素要么實(shí)現(xiàn)Comparable接口要么在構(gòu)造時(shí)傳入Comparator。它的優(yōu)勢(shì)是天生保證元素唯一性并且add,remove,first/last獲取最小/最大操作的時(shí)間復(fù)雜度都是 O(log N)。對(duì)于本題Pop操作相當(dāng)于取出并刪除集合中的“最大”元素根據(jù)我們定義的順序。TreeSet可以完美滿足需求。權(quán)衡PriorityQueue的remove(Object)操作是 O(N) 的如果我們需要?jiǎng)h除非堆頂?shù)奶囟ㄔ乇热鐬榱巳ブ囟葯z查存在性再插入效率不高。而TreeSet的所有關(guān)鍵操作都是 O(log N)。因此更推薦使用TreeSet 因?yàn)樗瑫r(shí)滿足了有序、去重和高效刪除的需求。方案二使用動(dòng)態(tài)數(shù)組如ArrayList 每次排序這是一種“懶惰”但實(shí)現(xiàn)簡(jiǎn)單的方案。每次執(zhí)行Pop時(shí)都對(duì)整個(gè)列表進(jìn)行排序然后取出最后一個(gè)元素假設(shè)按模降序、字典序升序排序。Insert時(shí)直接添加或先檢查重復(fù)。Size直接返回列表大小。優(yōu)點(diǎn)代碼極其簡(jiǎn)單易于理解和調(diào)試。缺點(diǎn)效率極低。每次Pop都是 O(N log N) 的復(fù)雜度如果操作次數(shù) M 很大總復(fù)雜度接近 O(M * N log N)無(wú)法通過(guò)大規(guī)模數(shù)據(jù)測(cè)試。僅適用于理解題目邏輯或數(shù)據(jù)量極小的場(chǎng)景不推薦作為最終解。方案三手動(dòng)維護(hù)有序鏈表或二叉搜索樹(shù)這屬于“硬核”實(shí)現(xiàn)方式能深刻鍛煉數(shù)據(jù)結(jié)構(gòu)的基本功。但在實(shí)際機(jī)試中時(shí)間有限除非題目明確要求否則不建議從頭實(shí)現(xiàn)容易出錯(cuò)。實(shí)操心得在限時(shí)上機(jī)考試中TreeSet 自定義Comparator是解決此類(lèi)“動(dòng)態(tài)維護(hù)一個(gè)有序唯一集合并需要頻繁取最值”問(wèn)題的最佳選擇。它直接利用了Java標(biāo)準(zhǔn)庫(kù)的成熟實(shí)現(xiàn)穩(wěn)定且高效。關(guān)鍵就在于正確編寫(xiě)那個(gè)比較器。3. 核心實(shí)現(xiàn)細(xì)節(jié)與代碼剖析3.1 復(fù)數(shù)類(lèi)的設(shè)計(jì)與比較邏輯首先我們需要一個(gè)Complex類(lèi)來(lái)封裝復(fù)數(shù)的實(shí)部和虛部并為其定義正確的相等和比較邏輯。class Complex { int real; // 實(shí)部 int imag; // 虛部 public Complex(int real, int imag) { this.real real; this.imag imag; } // 計(jì)算模的平方避免使用浮點(diǎn)數(shù) public long getModSquare() { return (long) real * real (long) imag * imag; } // 重寫(xiě)equals方法用于TreeSet去重或HashMap查找 Override public boolean equals(Object o) { if (this o) return true; if (o null || getClass() ! o.getClass()) return false; Complex complex (Complex) o; return real complex.real imag complex.imag; } // 重寫(xiě)hashCode與equals保持一致 Override public int hashCode() { return Objects.hash(real, imag); } // 便于輸出的toString方法 Override public String toString() { // 格式化輸出例如 (3, 5i) 或 35i return String.format((%d, %di), real, imag); } }注意事項(xiàng)使用long類(lèi)型存儲(chǔ)模的平方int類(lèi)型的最大值約為21億其平方可能超過(guò)int范圍約46億導(dǎo)致溢出。使用long是安全的。必須同時(shí)重寫(xiě)equals和hashCode如果我們要將Complex對(duì)象放入HashSet、HashMap或作為T(mén)reeSet的元素TreeSet雖然主要用比較器但某些內(nèi)部操作可能依賴這兩個(gè)方法必須正確重寫(xiě)且邏輯一致即相等的對(duì)象必須有相同的哈希碼。3.2 自定義比較器Comparator的精確實(shí)現(xiàn)這是整個(gè)程序的心臟。我們需要為T(mén)reeSet定義一個(gè)比較器定義何為“大”何為“小”。import java.util.Comparator; public class ComplexComparator implements ComparatorComplex { Override public int compare(Complex c1, Complex c2) { // 1. 首先比較模的平方降序 long modSq1 c1.getModSquare(); long modSq2 c2.getModSquare(); if (modSq1 ! modSq2) { // 我們希望模大的排在前面在TreeSet中是“小”的 // TreeSet是升序排列first()是最小的元素。 // 但我們希望Pop時(shí)拿到的是“模最大”的也就是我們定義的“最大”值。 // 所以如果我們定義c1“大于”c2時(shí)返回負(fù)數(shù)c1就會(huì)被排在c2前面更小的位置。 // 但first()取出的就是最小的即我們定義的“最大”的復(fù)數(shù)。 // 因此比較邏輯應(yīng)該是模大的復(fù)數(shù)在比較器中應(yīng)該返回“更小”的值。 return Long.compare(modSq2, modSq1); // 注意這里是modSq2和modSq1 } // 2. 模平方相等則按字典序先實(shí)部后虛部 if (c1.real ! c2.real) { return Integer.compare(c1.real, c2.real); // 實(shí)部小的字典序小返回負(fù)數(shù)排在前面 } // 實(shí)部也相等比較虛部 return Integer.compare(c1.imag, c2.imag); } }關(guān)鍵邏輯推導(dǎo)TreeSet是一個(gè)有序集合其迭代順序或first()、last()由比較器compare方法的返回值決定。如果compare(c1, c2)返回負(fù)數(shù)表示c1應(yīng)該排在c2前面即認(rèn)為c1“小于”c2。返回正數(shù)表示c1應(yīng)該排在c2后面即認(rèn)為c1“大于”c2。返回0認(rèn)為兩者相等TreeSet不會(huì)添加重復(fù)元素。我們的需求是Pop時(shí)取出當(dāng)前集合中“模最大”的若模相同取“字典序最小”的。在TreeSet中first()方法返回的是最小的元素根據(jù)比較器。因此我們需要將“模最大且字典序最小”的復(fù)數(shù)定義為比較器中的“最小”元素。這樣它就會(huì)被放在集合的最前面first()即可取得。模的比較對(duì)于c1和c2如果c1的模比c2大我們希望c1排在c2前面即更“小”。所以當(dāng)modSq1 modSq2時(shí)應(yīng)返回負(fù)數(shù)。Long.compare(modSq2, modSq1)正好滿足若modSq1 modSq2 則modSq2 modSq1compare返回負(fù)數(shù)。字典序比較當(dāng)模相等時(shí)字典序小的復(fù)數(shù)應(yīng)該更“小”即排在前面。所以實(shí)部小的返回負(fù)數(shù)虛部小的返回負(fù)數(shù)。Integer.compare(c1.real, c2.real)和Integer.compare(c1.imag, c2.imag)是標(biāo)準(zhǔn)的升序比較符合要求。避坑指南這個(gè)比較器的邏輯是本題最容易寫(xiě)錯(cuò)的地方。一個(gè)有效的測(cè)試方法是創(chuàng)建幾個(gè)復(fù)數(shù)手動(dòng)計(jì)算它們的模和字典序然后根據(jù)你的比較器推斷它們?cè)赥reeSet中的順序再用代碼驗(yàn)證first()取出的是不是你期望的那個(gè)。例如插入 (1,1) 模為√2 (0,2) 模為2。顯然(0,2)模更大first()應(yīng)該是(0,2)。再插入(0,-2)模也是2但字典序 (0,-2) (0,2)所以first()應(yīng)該變成(0,-2)。3.3 主程序流程與命令解析import java.util.Scanner; import java.util.TreeSet; public class ComplexCollection { public static void main(String[] args) { Scanner scanner new Scanner(System.in); // 使用自定義比較器初始化TreeSet TreeSetComplex set new TreeSet(new ComplexComparator()); while (scanner.hasNextLine()) { String line scanner.nextLine().trim(); if (line.equals(End)) { break; } if (line.startsWith(Insert)) { // 解析命令例如 Insert 35i 或 Insert (3, 5i) String numStr line.substring(6).trim(); // 去掉Insert // 移除可能存在的括號(hào)和i并分割實(shí)部虛部 numStr numStr.replaceAll([()i], ); // 移除(、)、i字符 String[] parts numStr.split(\\s*[,]\\s*); // 按或,分割允許周?chē)锌崭?if (parts.length ! 2) { // 處理可能的格式錯(cuò)誤簡(jiǎn)單起見(jiàn)可以跳過(guò)或提示 continue; } try { int real Integer.parseInt(parts[0]); int imag Integer.parseInt(parts[1]); Complex c new Complex(real, imag); set.add(c); // TreeSet會(huì)自動(dòng)去重 } catch (NumberFormatException e) { // 數(shù)字解析失敗忽略此命令 } } else if (line.equals(Pop)) { if (set.isEmpty()) { System.out.println(empty); } else { Complex maxComplex set.pollFirst(); // 取出并移除第一個(gè)即我們定義的“最小”實(shí)際是模最大字典序最小 System.out.println(maxComplex); // 調(diào)用toString輸出 // 或者按題目要求格式輸出例如35i // System.out.println(maxComplex.real maxComplex.imag i); } } else if (line.equals(Size)) { System.out.println(set.size()); } // 可以忽略無(wú)法識(shí)別的命令 } scanner.close(); } }命令解析的魯棒性輸入格式可能多變有的題目是abi 有的是(a, bi)。代碼中使用了簡(jiǎn)單的字符串替換和正則表達(dá)式分割來(lái)兼容多種格式。在實(shí)際考試中務(wù)必仔細(xì)閱讀題目規(guī)定的精確輸入格式有時(shí)一個(gè)空格都不能錯(cuò)。使用try-catch處理數(shù)字解析異常避免程序因非法輸入而崩潰。TreeSet的add方法在添加已存在元素時(shí)會(huì)返回false天然實(shí)現(xiàn)了去重。pollFirst()方法完美實(shí)現(xiàn)了Pop的功能檢索并移除第一個(gè)最小元素。4. 測(cè)試用例設(shè)計(jì)與邊界條件排查寫(xiě)完代碼不代表萬(wàn)事大吉設(shè)計(jì)全面的測(cè)試用例是保證ACAccepted的關(guān)鍵。4.1 常規(guī)功能測(cè)試基本插入與查詢Insert 34i Size Pop預(yù)期輸出1,(3, 4i)。模相同字典序比較Insert 05i // 模平方25 Insert 34i // 模平方25 Insert -34i // 模平方25 Pop Pop Pop預(yù)期輸出(-3, 4i),(0, 5i),(3, 4i)。因?yàn)樽值湫?-3) 0 3。去重測(cè)試Insert 11i Insert 11i Size預(yù)期輸出1。4.2 邊界與異常測(cè)試空集合操作Pop Size預(yù)期輸出empty,0。大數(shù)測(cè)試測(cè)試int邊界值防止模平方計(jì)算溢出。Insert 1000010000i Insert -10000-10000i Pop檢查程序是否能正確處理long類(lèi)型是否能容納10000*10000*2。負(fù)數(shù)與零Insert -50i Insert 0-3i Insert 00i Pop Pop Pop驗(yàn)證比較邏輯對(duì)負(fù)數(shù)和零的處理是否正確。(0,0i)的模為0。連續(xù)Pop直至空Insert 10i Pop Pop預(yù)期輸出(1, 0i),empty。4.3 性能壓力測(cè)試思考雖然上機(jī)環(huán)境可能不要求但自己可以思考如果操作數(shù) M 達(dá)到10^5使用ArrayList排序的方案必然超時(shí)。而TreeSet的方案每次Insert和Pop都是 O(log N)總復(fù)雜度 O(M log N)可以輕松應(yīng)對(duì)??梢詷?gòu)造數(shù)據(jù)先插入10^5個(gè)隨機(jī)復(fù)數(shù)然后交替進(jìn)行Pop和Insert。5. 常見(jiàn)問(wèn)題與調(diào)試技巧實(shí)錄在實(shí)際實(shí)現(xiàn)和調(diào)試過(guò)程中我遇到和總結(jié)的典型問(wèn)題如下問(wèn)題1Pop出來(lái)的元素不是模最大的或者順序不對(duì)。排查首先檢查比較器Comparator。這是最高發(fā)問(wèn)題區(qū)。務(wù)必用一組簡(jiǎn)單的測(cè)試數(shù)據(jù)手動(dòng)模擬。例如僅插入兩個(gè)模不同的復(fù)數(shù)看first()對(duì)不對(duì)。再插入兩個(gè)模相同但實(shí)部/虛部不同的復(fù)數(shù)看順序是否符合字典序定義。技巧在比較器實(shí)現(xiàn)中添加臨時(shí)的System.out.println打印比較過(guò)程觀察當(dāng)比較兩個(gè)特定復(fù)數(shù)時(shí)返回值是否符合你的預(yù)期。問(wèn)題2插入了重復(fù)的復(fù)數(shù)。排查檢查Complex類(lèi)的equals和hashCode方法是否被正確重寫(xiě)。TreeSet判斷元素是否重復(fù)首先依賴于compare方法返回0。如果比較器只比較模和字典序那么(3,4i)和(3,4i)的比較結(jié)果自然是0會(huì)被去重。但是如果后續(xù)需要用到HashSet或作為Map的鍵equals和hashCode就必須正確實(shí)現(xiàn)。一個(gè)良好的習(xí)慣是總是同時(shí)重寫(xiě)它們。注意如果比較器邏輯是compare(c1, c2)當(dāng)模和字典序都相同時(shí)返回0那么(3,4i)和(-3,-4i)模相同但實(shí)部虛部都不同不會(huì)被認(rèn)為是相等的。這符合集合的數(shù)學(xué)定義。問(wèn)題3輸入格式解析錯(cuò)誤導(dǎo)致NumberFormatException。排查題目輸入格式可能很“刁鉆”比如數(shù)字和符號(hào)之間可能有空格Insert ( 3 , 4i )或者沒(méi)有空格Insert 34i。你的字符串分割邏輯必須足夠健壯。使用trim()去除首尾空格使用靈活的正則表達(dá)式如\\s*[,]\\s*來(lái)分割。技巧在解析部分代碼完成后先不要寫(xiě)邏輯直接打印解析出來(lái)的實(shí)部和虛部字符串看看是否正確。問(wèn)題4輸出格式不符合要求導(dǎo)致“Presentation Error”。排查這是最可惜的錯(cuò)誤。題目要求輸出34i你輸出(3, 4i)即使答案對(duì)格式不對(duì)也不得分。務(wù)必一字不差地對(duì)照題目輸出樣例。修改Complex的toString()方法或主程序中的輸出語(yǔ)句。問(wèn)題5使用Scanner的nextInt()和nextLine()混用導(dǎo)致?lián)Q行符問(wèn)題。建議對(duì)于這類(lèi)行命令式輸入統(tǒng)一使用nextLine()讀取一整行然后進(jìn)行解析。避免nextInt()后留下的換行符被下一個(gè)nextLine()讀取到導(dǎo)致空字符串。終極調(diào)試建議在本地IDE中將題目中的樣例輸入保存為一個(gè)input.txt文件使用System.setIn(new FileInputStream(“input.txt”))重定向標(biāo)準(zhǔn)輸入。將你的程序輸出與樣例輸出逐行對(duì)比。這是最可靠的調(diào)試方法。6. 從這道題延伸出的實(shí)戰(zhàn)思考這道“復(fù)數(shù)集合”題雖然背景簡(jiǎn)單但它是一個(gè)絕佳的載體考察和串聯(lián)了多個(gè)核心知識(shí)點(diǎn)數(shù)據(jù)結(jié)構(gòu)的選擇能力面對(duì)“動(dòng)態(tài)獲取最值”的需求能否第一時(shí)間想到優(yōu)先隊(duì)列或有序集合能否在PriorityQueue和TreeSet之間做出正確的取舍這直接反映了你的基本功是否扎實(shí)。比較邏輯的抽象與實(shí)現(xiàn)能力定義“大小”或“優(yōu)先級(jí)”是編程中極其常見(jiàn)的需求。這道題要求綜合兩種規(guī)則模、字典序來(lái)定義序關(guān)系。能否清晰、無(wú)歧義地實(shí)現(xiàn)Comparator是區(qū)分代碼是否健壯的關(guān)鍵。面向?qū)ο蟮脑O(shè)計(jì)能力將復(fù)數(shù)抽象成Complex類(lèi)將數(shù)據(jù)與操作分離讓主邏輯更清晰。良好的封裝如將模平方計(jì)算放在類(lèi)內(nèi)也體現(xiàn)了代碼質(zhì)量。邊界條件與魯棒性處理空集合、非法輸入、大數(shù)溢出等問(wèn)題是一個(gè)程序員寫(xiě)出工業(yè)級(jí)代碼的必備素質(zhì)。上機(jī)考試往往有隱藏的邊界測(cè)試點(diǎn)。字符串處理與解析在實(shí)際工作中處理非標(biāo)準(zhǔn)格式的輸入輸出如日志解析、API數(shù)據(jù)抓取是家常便飯。這道題的命令解析部分就是一個(gè)微型演練。所以不要把它僅僅當(dāng)作一道算法題。試著把它當(dāng)作一個(gè)微型項(xiàng)目來(lái)對(duì)待定義需求題目、設(shè)計(jì)數(shù)據(jù)結(jié)構(gòu)與接口Complex類(lèi)、比較器、實(shí)現(xiàn)核心邏輯命令處理、編寫(xiě)測(cè)試用例、處理異常。通過(guò)這樣一道題你所鍛煉和展示的能力遠(yuǎn)比AC通過(guò)本身更有價(jià)值。在面試中你也可以用這道題為例來(lái)闡述你對(duì)這些知識(shí)點(diǎn)的理解這比干巴巴地背誦概念要生動(dòng)得多。