- 题目详述
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
二.自我探寻(较慢21ms,网络学习过程10ms)
思路:举例
(1)13156-》13165
(2)13152-》13215
(3)24321-》31224
从倒数第二位开始向前
若后面存在比它大的数 在这些比它大的数中挑个最小的与之交换 然后对后面的数进行升序排列
- 从5开始,6比5大,交换变成13165,对5进行升序排列仍是13156
- 从5开始,没有比5大的,再看倒数第三位1 ,5和2都比1大,2比较小 交换 变成 13251 对倒数第三位后面的数进行升序排列 13215
- 从2(倒数第二位的)开始,后面没有比它大的
到3,后面没有比它大的
到4,后面没有比它大的
到2(第一位的),比他大的有 4 3 选择较小的3,变成34221
对第一位后面的进行排序,变成31224
代码:
class Solution {
public void nextPermutation(int[] nums) {
if(nums.length==1)
return;
int minx=nums.length-1;
int maxx=nums.length-1;
for(int q=nums.length-2;q>=0;q--)
{
if(nums[q]>=nums[maxx])
{
maxx=q;
if(q==0)
{
sort(0, nums.length-1, nums);
}
continue;
}
else if(nums[q]<nums[minx])
{
swap(q,minx,nums);
sort(q+1,nums.length-1,nums);
break;
}
else {
swap(q,search(q,nums) , nums);
sort(q+1, nums.length-1, nums);
break;
}
}
}
public static void swap(int i,int j,int[] nums)
{
int s=nums[i];
nums[i]=nums[j];
nums[j]=s;
}
public static void sort(int i,int j,int[] nums)/**从第i位开始快排**/
{
int m=i;
int n=j;
if(m>=n)
{
return;
}
while(m<n)
{
while(m<n&&nums[n]>=nums[i])
{
n--;
}
while(m<n&&nums[m]<=nums[i])
{
m++;
}
if(m<n)
{
swap(m,n,nums);
}
}
swap(i, n, nums);
sort(n+1,j, nums);
sort(i,n-1, nums);
}
public static int search(int q,int[] nums)/**返回比它大的最小的数的下标,t是传入的数的座标*/
{
int min=Integer.MAX_VALUE;
int minx=0;
for(int f=q+1;f<nums.length;f++)
{
if(nums[f]-nums[q]<min&&nums[f]-nums[q]>0)
{
min=nums[f]-nums[q];
minx=f;
}
}
return minx;
}
}
评价:
- 网络学习过程
思路:(1)13156-》13165
(2)13152-》13215
(3)24321-》31224
观察交换位后面 的数组 (1)5(2)52(3)4321
仔细思考后会发现从后往前降序排列断掉的一位正是 交换位
搜寻大的时候可以用二分法(代码中没用)
最后仍是降序数组 直接翻转 为升序数组
代码:public class Solution {
public void nextPermutation(int[] nums) {
int i = nums.length - 2;
while (i >= 0 && nums[i + 1] <= nums[i]) {
i--;
}
if (i >= 0) {
int j = nums.length - 1;
while (j >= 0 && nums[j] <= nums[i]) {
j--;
}
swap(nums, i, j);
}
reverse(nums, i + 1);
}
private void reverse(int[] nums, int start) {
int i = start, j = nums.length - 1;
while (i < j) {
swap(nums, i, j);
i++;
j--;
}
}
private void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
评价:10ms
四.Python实现