原題地址:https://oj.leetcode.com/problems/next-permutation/
題意:
Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.
If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).
The replacement must be in-place, do not allocate extra memory.
Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
解題思路:輸出字典序中的下一個排列。比如123生成的全排列是:123,132,213,231,312,321。那么321的next permutation是123。下面這種算法據說是STL中的經典算法。在當前序列中,從尾端往前尋找兩個相鄰升序元素,升序元素對中的前一個標記為partition。然后再從尾端尋找另一個大於partition的元素,並與partition指向的元素交換,然后將partition后的元素(不包括partition指向的元素)逆序排列。比如14532,那么升序對為45,partition指向4,由於partition之后除了5沒有比4大的數,所以45交換為54,即15432,然后將partition之后的元素逆序排列,即432排列為234,則最后輸出的next permutation為15234。確實很巧妙。
代碼:
class Solution: # @param num, a list of integer # @return a list of integer def nextPermutation(self, num): if len(num) <= 1: return num partition = -1 for i in range(len(num)-2, -1, -1): if num[i] < num[i+1]: partition = i break if partition == -1: num.reverse() return num else: for i in range(len(num)-1, partition, -1): if num[i] > num[partition]: num[i],num[partition] = num[partition],num[i] break left = partition+1; right = len(num)-1 while left < right: num[left],num[right] = num[right],num[left] left+=1; right-=1 return num
改進一點:
class Solution: # @param num, a list of integer # @return a list of integer def nextPermutation(self, num): if len(num) <= 1: return num partition = -1 for i in range(len(num)-2, -1, -1): if num[i] < num[i+1]: partition = i break if partition == -1: num.reverse() return num else: for i in range(len(num)-1, partition, -1): if num[i] > num[partition]: num[i],num[partition] = num[partition],num[i] break num[partition+1:len(num)]=num[partition+1:len(num)][::-1] return num