具代表性的面試主題

程式面試:如何原地求下一個字典序排列?

程式題中等
Offer.cc 編輯團隊發佈 更新

題幹

給定可能含重複值的整數陣列,請原地改成字典序嚴格較大的下一個排列;若不存在則改成最小排列。請說明轉折點、交換、後綴處理與邊界。

面試官考察點

給定可能含重複值的整數陣列,請原地改成字典序嚴格較大的下一個排列;若目前已是最大排列,則改成升序的最小排列。

約束與邊界

  • 只能使用 O(1) 額外空間,允許交換與反轉。
  • 重複值不能被當成不同元素計數,但比較仍按數值進行。
  • 陣列為空或只有一個元素時,操作保持不變。
  • 必須是全域字典序的下一個排列,不能只交換相鄰元素。

找到最右側轉折點

從右向左找到第一個滿足「左值嚴格小於右值」的位置 i。右側已是非遞增後綴;若找不到轉折點,整個陣列降序,反轉即可得到最小排列。

交換後再最小化後綴

有轉折點時,從右向左找第一個大於 nums[i] 的元素 j。因為後綴非遞增,首次找到的就是最小可行較大值。交換 ij,再反轉 i + 1 之後的後綴,使變化幅度最小。

30 秒回答框架

「我從右找第一個上升轉折點 i。若不存在,陣列已是最大排列,直接反轉。否則從右找第一個大於 nums[i]j,交換兩者,再把右側後綴反轉成升序。後綴原本非遞增,所以這三步得到嚴格較大的最小候選,時間 O(n)、空間 O(1)。 」

回答前需要釐清的問題

  • 是否要求原地修改?若允許額外空間,可以排序複製;原地要求決定反轉方案。
  • 「下一個」按數字升序還是字串比較?負數與多位數時語意不同。
  • 元素是否可能重複?重複值決定尋找嚴格大於而不是大於等於。

分步驟深入解答

設陣列為 [1,2,3],轉折點是 1 的位置,交換後綴中最小的大於它的 2,得到 [2,1,3],再反轉後綴仍為 [2,1,3]。對 [3,2,1] 找不到轉折點,反轉成 [1,2,3]

text
i = n - 2
while i >= 0 and nums[i] >= nums[i + 1]:
    i -= 1
if i >= 0:
    j = n - 1
    while nums[j] <= nums[i]:
        j -= 1
    swap(nums[i], nums[j])
reverse(nums, i + 1, n - 1)

等值元素使用「大於等於」關係跳過轉折候選,使用「小於等於」關係跳過交換候選,保證變化嚴格增加。後綴反轉而非排序,是因為轉折點右側已經有序,反轉可在線性時間完成。

高品質示範回答

「字典序下一個排列要先讓盡可能靠右的位置變大,同時讓後綴盡可能小。我從右找最右的『左值嚴格小於右值』轉折點;從右找第一個大於它的值交換,接著反轉後綴。沒有轉折點表示已是最大排列,反轉整個陣列。掃描、交換和反轉都是 O(n),只用常數變數。」

常見錯誤

  • 從左找轉折點,讓更高位改變,跳過中間排列。
  • 交換後直接結束,沒有把後綴變成最小順序。
  • 用大於等於尋找交換值,重複值可能無法嚴格變大。
  • 對後綴呼叫通用排序,空間或複雜度超出原地要求。
  • 沒有處理完全降序陣列,回傳原陣列而不是最小排列。

錯誤表現與修正

[1,3,2] 若回傳 [3,1,2],表示轉折點選得太靠左;正確結果是 [2,1,3]。對 [1,1,5] 若交換相等元素,表示嚴格比較邊界錯誤。

生產化實作

封裝只接受可變隨機存取序列的函式,讓反轉使用雙指標。若元素型別可能溢出比較或跨語言比較規則不同,在介面層明確排序關係與異常輸入策略。

驗證清單

測試空陣列、單元素、完全升序、完全降序、重複值、轉折在末端和多個最佳排列。對小陣列生成所有不重複排列,按字典序排序後逐個驗證函式輸出的下一個元素。

追問及應對

為什麼一定要找最右轉折點?

越靠右的轉折點代表越小的高位變化;在它右側尋找交換值並最小化後綴,才能得到目前排列之後的緊鄰排列。

後綴為什麼可以直接反轉?

轉折點是從右找到的,因此右側原本非遞增。交換較大值後,剩餘後綴仍可透過反轉恢復為升序最小狀態。

如果要求第 k 個下一個排列呢?

重複執行會產生 O(k n) 時間;若 k 很大,可研究計數排列、跳躍或直接按排名解碼,但需要額外組合計數與重複值處理。

評分標準

  • 轉折點正確:從右尋找最右的嚴格上升位置。
  • 交換正確:從右尋找第一個嚴格較大的值。
  • 後綴正確:交換後反轉為最小升序。
  • 邊界完整:覆蓋降序、重複、空陣列和單元素。
  • 複雜度準確:O(n) 時間、O(1) 額外空間。

合規檢查

確認三步演算法、邊界案例與複雜度結論在回答中保持一致。

面試作答要點

先解釋「右側最小變化」,再寫轉折、交換和反轉三步;用重複值例子說明嚴格比較,最後給出複雜度和全排列對拍。

一句話總結

下一個排列透過最右轉折點、最小可行交換值與後綴反轉,在原地 O(n) 時間得到字典序緊鄰結果。

公開來源

同類題目

相關面試工具

用 Screenshot 處理演算法題

截圖題目後,依序看約束、解法、程式碼、邊界條件和複雜度。

查看工具