這一題是一種數學題,如果數學想通了就很好解,沒想通,那就只好琢磨到理解為止。
這裡要講如何理解。以 [4,2,3,1] 排組為例。
如果要找到下一個,就只要從右方移一個(從尾開始),讓該組合的大小略增即可。
那要跟誰換呢?從右方開始,如果該位置的值比左方的大,那就是目標位置。
如果左方皆 >= 右方,那代表該組合是最大的。如 [4,3,2,1] [5,1,1]
([4,【2,3】,1])※選左右哪方當目標位置都可以。這裡用左右,必免混淆。
接著從目標位置右及右方開始選一個大於目標位置左的最小值,二者互相交換。可以想成進位。
([4,【2(左),3(右)】,1] -> [4,2,【3,1】] -> [4,2,【3】,1] -> [4,3,2,1])
換完之後,目標位置右方,應該要變成小到大的排序﹐才會是下一個組合。
([4,【3】,2,1] -> [4,3,1,2])
在換之前,目標位置右及右方已經是非升序排列(左>=右),若把它看成一個排列組合,那此時的右方排列會是該排列組合中最大的。
最大的組合,只要反序,就會回到最小的組合。
若碰到 [4,3,2,1],目標位置會在 4 的前方,沒辦法交換,所以直接把數列反序即可。
而交換之後,右方的非升序排列的性質依舊不變,因此只要把右方反序,就會變成右方最小的組合。
反序之後的組合就是題目所求。
流程 |
Python
class Solution: def nextPermutation(self, nums) -> None: n = len(nums) si = n - 1 while si > 0 and nums[si] <= nums[si-1]: si -= 1 while si: for j in range(n-1, si-1, -1): if nums[j] > nums[si-1]: nums[si-1], nums[j] = nums[j], nums[si-1] nums[si:] = nums[si:][::-1] return si -= 1 nums[si:] = nums[si:][::-1]