實現獲取下乙個排列的函式——
將給定數字序列重新排列成字典序中下乙個更大的排列。
如果不存在下乙個更大的排列,則將數字重新排列成最小的排列(即公升序排列)。
字典序(dictionary order),又稱 字母序(alphabetical order),原意是表示英文單詞在字典中的先後順序,在計算機領域中擴充套件成兩個任意字串的大小關係。
對於兩個字串,大小關係取決於兩個字串從左到右第乙個不同字元的 ascii 值的大小關係。
class solution
};
先判斷特殊情況
當排列元素個數為0,1時,下乙個排列為其自身,直接返回即可
//判斷特殊情況
int n = nums.size();
if(n == 1 || n == 0)return;
然後找到滿足條件的小數
怎麼找呢?
我們首先要明確
若nums[index+1]>nums[index+2]>……>nums[n-1]
我們是不可能由下標index後面的元素經過排列得到更大的排列的
所以我們要找的小數即是從後往前第乙個使得nums[index] < nums[index+1]的下標對應的元素
//找小數
int index = n-2;
while(index > 0 && nums[index] >= nums[index+1])
宣告要用到的臨時變數
int tmp,il,ir;
然後在nums[index+1],nums[index+2]……nums[n-1]找到比小數大的最小的元素,也即我們要找的大數
//找大數
tmp = nums[index];ir = n-1;
while(nums[ir] <= tmp && ir > index)
--ir;
交換大數nums[ir],小數nums[index]
//交換大數和小數
nums[index] = nums[ir];nums[ir] = tmp;
這裡要留意由於可能不存在下乙個更大的排列,
這裡我們要做個判斷,
如果不存在,也就是說這個排列已經是最大的排列了
也就不需要找大數了,直接逆序
否則需要找大數和交換大數和小數
所以**應該是這樣的
if(index >= 0)
這個時候,已經得到更大的排列
但我們想要增大幅度更小的排列
我們可以看到,經過交換後,
下標index後面的元素仍然滿足降序
這時我們想讓它們變為公升序排列
只需要簡單地讓它們不斷首尾交換實現逆序即可
//降序轉公升序
il = index+1;ir = n-1;
while(il < ir)
最後整體**如下
class solution int tmp,il,ir;
//判斷是否已為最大的排列
//若不是,則需要找大數並與小數交換
if(index >= 0)
il = index+1;ir = n-1;
//降序轉公升序
while(il < ir)
}};
總的來說,實現思路如下
從後往前找小數
由小到大找大數
交換大數和小數
剩餘降序轉公升序
leetcode 31 下乙個排列
實現獲取下乙個排列的函式,演算法需要將給定數字序列重新排列成字典序中下乙個更大的排列。如果不存在下乙個更大的排列,則將數字重新排列成最小的排列 即公升序排列 必須原地修改,只允許使用額外常數空間。以下是一些例子,輸入位於左側列,其相應輸出位於右側列。1,2,3 1,3,2 3,2,1 1,2,3 1...
leetCode 31 下乙個排列
思路就是找到可以變大的最低位,進一步說,就是找到,nums pos 滿足,存在q使得,q pos 且 nums pos nums q 同時要注意的是,最終的答案要取q的下界。這是因為要找剛剛好比所給數字大的數字,所以我們要使得pos位,增大的盡量小。class solution else if nu...
LeetCode31 下乙個排列
實現獲取下乙個排列的函式,演算法需要將給定數字序列重新排列成字典序中下乙個更大的排列。如果不存在下乙個更大的排列,則將數字重新排列成最小的排列 即公升序排列 必須原地修改,只允許使用額外常數空間。以下是一些例子,輸入位於左側列,其相應輸出位於右側列。1,2,3 1,3,2 3,2,1 1,2,3 1...