Next Permutation

来源:互联网 发布:数组一般什么时候用 编辑:程序博客网 时间:2024/05/17 08:14

问题描述

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

思考:如何反转,替换才能达到目的

想法:

  • 1、从后往前,找出num[i] < num[i + 1]的i,然后,在(i + 1 , num.length - 1)中找出num[i]应该插入的位置j(即保证从i + 1 到 num.length - 1,序列为逆序,且num[j] > num[i]>num[j+1]),调换num[i] 和num[j]的值.(找j的过程可以用二分查找)
  • 2、对i + 1到num.length的序列逆序(先逆序再调换顺序也一样,)

代码:

没有二分查找,且先替换,再逆序

/** * Created by Risky on 2015/4/20. */public class Solution {    public void nextPermutation(int[] num) {        int len = num.length;                if(len < 2)            return;               int index1 = len - 2;        while(index1 >= 0 && num[index1] >= num[index1 + 1])            index1--;        int index2 = index1 + 1;               while(index1 >=0 && index2 < len && num[index2] > num[index1] )            index2++;        if(index1 >= 0 && index2 <= len)            swap(num,index1,index2 - 1);        reverse(num,index1 + 1,len - 1);    }    private void swap(int[] num, int i, int j){        int temp = num[i];        num[i] = num[j];        num[j] = temp;    }    private void reverse(int [] num, int start, int end){        if(start == end)            return;        int mid = (start + end) >> 1;        for(int i = start; i <= mid; i++)            swap(num,i,end + start - i);    }}

带二分查找,先逆序,再替换

/** * Created by Risky on 2015/4/20. */public class Solution {    public void nextPermutation(int[] num) {        int len = num.length;        if(len < 2)            return;        int index1 = len - 2;        while(index1 >= 0 && num[index1] >= num[index1 + 1])            index1--;        reverse(num,index1 + 1,len - 1);        if(index1 ==  -1)            return;        int index2 =  find(num,index1 + 1,len - 1, num[index1]);        if(index2 <= len)            swap(num,index1,index2);    }    public int find(int[] num, int start, int end, int target) {        while(start < end){            int mid = (start + end) >> 1;            if(target >= num[mid])                start= mid + 1;            else              end = mid;        }        return   start;    }    private void swap(int[] num, int i, int j){        int temp = num[i];        num[i] = num[j];        num[j] = temp;    }    private void reverse(int [] num, int start, int end){        if(start == end)            return;        int mid = (start + end) >> 1;        for(int i = start; i <= mid; i++)            swap(num,i,end + start - i);    }}
0 0
原创粉丝点击