previous and next permutation

Posted tobeabetterpig

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了previous and next permutation相关的知识,希望对你有一定的参考价值。

previous and next permutation 
2763541 (找最后一个正序35)    
    2763541 (找3后面比3大的最后一个数4)
    2764531 (交换3,4的位置)
    2764135 (把4后面的5,3,1反转)
2764135 (找最后一个逆序41)    
    2764135 (找4后面比4小的最后一个数3)
    2763145 (交换3,4的位置)
    2763541 (把3后面的1,4,5反转)


https://github.com/tongzhang1994/Facebook-Interview-Coding/blob/master/Previous%20Permutation.java



Next permutation
https://www.youtube.com/watch?v=w58KFpW5Pjk


class Solution {
    public void nextPermutation(int[] nums) {
        if(nums == null || nums.length == 0){
            return;
        }
        
        int replace = nums.length - 2;
        while(replace >= 0){
            if(nums[replace] < nums[replace + 1]){
                break;
            }else{
                replace--;
            }
        }
        
        if(replace < 0){
            Arrays.sort(nums);
            return;
        }
        
        int largeIndex = replace + 1;
        while(largeIndex < nums.length && nums[largeIndex] > nums[replace]){
            largeIndex++;
        }
        
        int tmp = nums[replace];
        nums[replace] = nums[largeIndex - 1];
        nums[largeIndex - 1] = tmp;
        Arrays.sort(nums, replace + 1, nums.length);
        
    }
}

比如对于725321来说,由于5321由于从最低位到最高位是升序排列,已经达到该四位数字permutation的最大值。这时不得不改变第5位的2来增加数值。如何改变?为了使增量最小,在前4位中比第5位大的数(5, 3)中找一个最小的数,即数字3。用3替换2,而剩下5, 2, 2, 1四个数字要组成最低4位。由于第5位已经从2增加到3,同样为了使增量最小,我们希望剩下的4位数尽可能小。所以将他们从低到高位降序排列即可。总结上面的思考:

1. 从低位向高位(从右向左)找第一个递减的数:s[i]<s[i+1]。如果不存在,则表明该permutation已经最大,next permutation为当前序列的逆序。
2. 在s[i+1:n-1]中找一个j,使s[j]>s[i]>=s[j+1],swap(s[i], s[j])
3. 将s[i+1:n-1]排序,从低位到高位单调递减。






Previous permutation 


// not tested yet

    class Solution {
        public int[] prev(int[] array) {
            int index = array.length - 2;
            while (index >= 0) {
                if (array[index] > array[index + 1]) {
                    break;
                } else {
                    index--;
                }
            }

            if (index < 0) {
                reverse(array, 0, array.length - 1);
                return array;
            }


            //else
            int smaller = index;
            while (smaller < array.length) {
                if (array[smaller] <= array[index]) {
                    smaller++;
                }
            }

            //
            int suitable = smaller - 1;

            // swap suitable with the num in index
            swap(array, suitable, index);

            // now reverse the leftover after the index
            // in descending order
            reverse(array, index + 1, array.length - 1);

            return array;
        }

        private void reverse(int[] array, int start, int end) {
            while (start < end) {
                swap(array,start,end);
            }
        }
      
        private void swap(int[] array, int i, int j){
          int tmp = array[i];
          array[i] = array[j];
          array[j] = tmp;
        }
    }
}

 

以上是关于previous and next permutation的主要内容,如果未能解决你的问题,请参考以下文章

wod按next和previous post link

我想知道基于哪个时区或区域设置 MAQL 时间 marcos 'THIS'、'PREVIOUS'、'NEXT' 工作

html 使用Jquery的Next和Previous分页

ListIterator 在 next() 和 previous() 的交替调用中重复元素

Next Previous 使用 Android Listview 和 JSON 数据

在注释分页中替换WORDPRESS NEXT和PREVIOUS