題目描述:
實(shí)現(xiàn)獲取下一個(gè)排列的函數(shù)速警,算法需要將給定數(shù)字序列重新排列成字典序中下一個(gè)更大的排列掺冠。如果不存在下一個(gè)更大的排列,則將數(shù)字重新排列成最小的排列(即升序排列)腿宰。
必須原地修改,只允許使用額外常數(shù)空間。
示例:
以下是一些例子台谍,輸入位于左側(cè)列,其相應(yīng)輸出位于右側(cè)列责语。
1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
解答:
public static void nextPermutation(int[] nums) {
/*
* 1.判斷按照字典序有木有下一個(gè),如果完全降序就沒(méi)有下一個(gè)
* 2.如何判斷有木有下一個(gè)呢目派?只要存在a[i-1] < a[i]的升序結(jié)構(gòu)坤候,就有,
* 而且我們應(yīng)該從右往左找企蹭,一旦找到白筹,因?yàn)檫@樣才是真正下一個(gè)
* 3.當(dāng)發(fā)現(xiàn)a[i-1] < a[i]的結(jié)構(gòu)時(shí),從在[i,∞]中找到最接近a[i-1]并且又大于a[i-1]的數(shù)字谅摄,由于降序遍蟋,從右往左遍歷即可得到k
* 4.然后交換a[i-1]與a[k],然后對(duì)[i, ∞]排序即可螟凭, 排序只需要首尾不停交換即可,因?yàn)橐呀?jīng)是降序
* 上面說(shuō)的很抽象它呀,還是需要拿一些例子思考才行螺男,比如[0,5,4,3,2,1],下一個(gè)是[1,0,2,3,4,5]
*/
int i = nums.length - 2;
// 從右往左找到第一個(gè)逆序數(shù)
while (i >= 0 && nums[i] >= nums[i + 1]) {
i--;
}
// 第一個(gè)逆序元素與大于這個(gè)逆序數(shù)的值交換
if (i >= 0) {
int j = nums.length - 1;
while (j >= 0 && nums[j] <= nums[i]) {
j--;
}
swap(nums, i, j);
}
// 即使沒(méi)找到第一個(gè)逆序數(shù)【nums已降序】纵穿,將數(shù)組逆序排序【升序】
// 交換之后下隧,需要將交換后的第一個(gè)逆序元素之后的元素進(jìn)行升序排序【因?yàn)樵纫呀?jīng)是降序】
reverse(nums, i + 1);
}
// 將降序數(shù)組反轉(zhuǎn)為升序數(shù)組的方法1,left++谓媒;right--淆院;
private static void reverse(int[] nums, int start) {
// 將降序數(shù)組反轉(zhuǎn)為升序數(shù)組的方法,left++句惯,mid=sum/2土辩,start和end不確定
// private static void reverse3(int[] nums, int start,int end) : int i = start, j = end;
int i = start, j = nums.length - 1;
while (i < j) {
swap(nums, i, j);
j--;
i++;
}
}
// 將降序數(shù)組反轉(zhuǎn)為升序數(shù)組的方法2支救,left++,mid=sum/2
private static void reverse1(int[] nums, int start) {
// 將降序數(shù)組反轉(zhuǎn)為升序數(shù)組的方法拷淘,left++各墨,mid=sum/2,start和end不確定
// private static void reverse4(int[] nums, int start,int end) : int sum = start + end + 1;
int sum = start + nums.length - 1;
int mid = sum / 2;
for (; start <= mid; start++) {
int tmp = nums[start];
nums[start] = nums[sum - start];
nums[sum - start] = tmp;
}
}
private static void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
注意:
1.逆序的兩種方式【right和mid】
2.mid中启涯,sum為start + nums.length-1時(shí)贬堵,start<=mid【如果sum=2】