您的位置:首页 > 编程语言 > Java开发

[leetcode]31.Next Permutation(Java实现)

2017-06-20 09:49 288 查看
测试地址:https://leetcode.com/problems/next-permutation/#/description

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


Subscribe to see which companies asked this question.

题意(目的是找到比当前排序大1的新排序)

寻找比当前排列顺序大的下一个排列。

因为降序序列是没法变的更大的,所以从后往前找到第一个升序对的位置。

然后就存在调整大小排列顺序的可能,从后往前找到比当前位置大的元素,交换之。

当前位置后面的元素还是降序排列,将他们反转得到最小顺序排列。其实就是原来当前位置元素后面是最大的排列,而交换后的新元素之后是最小的排列,他们就是相邻的顺序。

当不存在升序,则当前排列是最大排列,只要旋转整个序列变成最小排列。

找给定序列的下一个字典序中的序列。

思想:

1、从右往左找第一个不满足升序的数,记该数下标为i;

2、从右往左找第一个比该数大的数,记下标味j;

3、交换两数:swap(num[i],num[j]);

4、将下标i+1到最后的数字反转;

网上寻找的另一个解释:

首先我们必须了解什么是“下一个”排列组合。考虑三个字符所组成的序列{a,b,c}。
      这个序列有六个可能的排列组合:abc,acb,bac,bca,cab,cba。这些排列组合根据less-than操作符做字典顺序(lexicographical)的排序。也就是说,abc名列第一,因为每一个元素都小于其后的元素。acb是次一个排列组合,因为它是固定了a(序列内最小元素)之后所做的新组合。
      同样道理,那些固定b(序列中次小元素)而做的排列组合,在次序上将先于那些固定c而做的排列组合。以bac和bca为例,bac在bca之前,因为次序ac小于序列ca。面对bca,我们可以说其前一个排列组合是bac,而其后一个排列组合是cab。序列abc没有“前一个”排列组合,cba没有“后一个”排列组合。
     next_permutation()会取得[first,last)所标示之序列的下一个排列组合,如果没有下一个排列组合,便返回false;否则返回true。这个算法有两个版本。版本一使用元素型别所提供的less-than操作符来决定下一个排列组合,版本二则是以仿函数comp来决定。

Java code:

public void nextPermutation(int[] nums) {
if (nums == null || nums.length < 2)
return;
int index = nums.length - 1;

while (index > 0) {
if (nums[index - 1] < nums[index])
break;
index--;
}
// index为0,说明该数组是完全递减的
if (index == 0)
reverseSort(nums, 0, nums.length - 1);
else {
// 说明存在递增序列
index--;
int n = nums.length - 1;
while (true) {
if (nums
> nums[index])
break;
n--;
}
swap(nums, index, n);
reverseSort(nums, index + 1, nums.length - 1);
}
}
/*
* 将数组逆序排列
*/
private void reverseSort(int[] nums, int start, int end) {
for (int i = start; i < (start + end + 1) / 2; i++)
swap(nums, i, end - i + start);
}

/*
* 交换数组中任意两个元素位置
*/
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: