Total Accepted: 91019
Total Submissions: 325010
Difficulty: Medium
Contributors: Admin
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
Hide Company Tags
Google
Hide Tags
Array
Hide Similar Problems
(M) Permutations (M) Permutations II (M) Permutation Sequence (M) Palindrome Permutation II
**解題思路 **
在當(dāng)前序列中惋鹅,從尾端往前尋找兩個相鄰元素赔退,前一個記為first隔嫡,后一個記為second,并且滿足first 小于 second。然后再從尾端尋找另一個元素number哄褒,如果滿足first 小于number,即將第first個元素與number元素對調(diào),并將second元素之后(包括second)的所有元素顛倒排序门驾,即求出下一個序列
example:
6,3多柑,4奶是,9,8竣灌,7聂沙,1
此時 first = 4,second = 9
從尾巴到前找到第一個大于first的數(shù)字初嘹,就是7
交換4和7及汉,即上面的swap函數(shù),此時序列變成6屯烦,3坷随,7,9驻龟,8温眉,4,1
再將second=9以及以后的序列重新排序翁狐,讓其從小到大排序类溢,使得整體最小,即reverse一下(因為此時肯定是遞減序列)
得到最終的結(jié)果:6露懒,3闯冷,7,1懈词,4窃躲,8,9
// [1, 3, 2] -> [2, 1, 3]
// https://discuss.leetcode.com/topic/30212/easiest-java-solution/2
public void nextPermutation(int[] nums) {
if (nums == null || nums.length <= 1) return;
int i = nums.length - 2;
while (i >= 0 && nums[i] >= nums[i + 1]) i--; // Find 1st id i that break descending order
if (i >= 0) { // If not entirely descending
int j = nums.length - 1; // Start from end
while (nums[j] <= nums[i]) j--; // Find rightmost first larger id j
swap(nums, i, j); // Switch i and j
}
reverse(nums, i + 1, nums.length - 1); // Reverse the descending sequence
}
public void swap(int[] nums, int i, int j ) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public void reverse(int[] A, int i, int j) {
while(i < j) swap(A, i++, j--);
}
// 第二種寫法
public void nextPermutation(int[] nums) {
if (nums == null || nums.length <= 1) return;
int i = nums.length - 1;
for (; i >=1 ; i--) {
if (nums[i] > nums[i - 1]) { // find first number which is smaller than it's after number
break;
}
}
if (i != 0) {
swap(nums, i - 1); // if the number exist, which means that nums not like { 5, 4, 3, 2, 1}
}
reverse(nums, i);
}
private void swap(int[] a, int i) {
for (int j = a.length - 1; j > i; j--) {
if (a[j] > a[i]) {
int t = a[j];
a[j] = a[i];
a[i] = t;
break;
}
}
}
private void reverse(int[] a, int i) { // reverse the number after the number we have found
int first = i;
int last = a.length - 1;
while (first < last) {
int t = a[first];
a[first] = a[last];
a[last] = t;
first++;
last--;
}
}