【LeetCode】31. Next Permutation

【题目】

将给定的元素进行全排列,给定一个排列,求基于字典序进行排序的下一个排列

eg:    1,2,3 → 1,3,2
   3,2,1 → 1,2,3
   1,1,5 → 1,5,1

【思路】贴上官方题解图

【代码】

 1 // 交换数组中元素
 2     private void swap(int[] arr, int a, int b) {
 3         int temp = arr[a];
 4         arr[a] = arr[b];
 5         arr[b] = temp;
 6     }
 7     // 反转
 8     private void reverse(int[] arr, int begin, int end) {
 9         while(begin<end) {
10             swap(arr, begin, end);
11             begin++;
12             end--;
13         }
14     }
15     public void nextPermutation(int[] nums) {
16         for(int i=nums.length-1;i>=1;--i) {
17             if(nums[i-1]<nums[i]) {
18                 int k = nums.length-1;
19                 while(nums[k]<=nums[i-1]) k--;
20                 swap(nums, k, i-1);
21                 reverse(nums, i, nums.length-1);
22                 return;
23             }
24         }
25         reverse(nums, 0, nums.length-1);
26     }
View Code

 

【拓展】

  打印全排列的三种方法

(1)递归打印

private void swap(char[] s, int a, int b) {
        char temp = s[a];
        s[a] = s[b];
        s[b] = temp;
    }
    // 从第一个数字起每个数分别与它后面的数字交换
    // 该方法遇到有重复的元素就会失效
    public void recursion(char[] s, int index) {
        if(index == s.length) {
            System.out.println(s);
        }
        
        for(int i=index;i<s.length;++i) {
            swap(s, index, i);
            recursion(s, index+1);
            swap(s, index, i); // 要记得换回来
        }
    }
    
    public static void main(String[] args) {
        char[] s = new char[] {'a', 'b', 'c'};
        new Permutation().recursion(s, 0);
    }
方法一

(2)递归打印非重复

// 检查s[a]~s[b]中间是否存在多个s[b]
    private boolean isRepeat(char[] s, int a, int b) {
        for(int i=a;i<b;++i) {
            if(s[i] == s[b]) return true;
        }
        return false;
    }
    public void recursionNoRepeat(char[] s, int index) {
        if(index == s.length) {
            System.out.println(s);
        }
        for(int i=index;i<s.length;++i) {
            if(!isRepeat(s, index, i)) {
                swap(s, index, i);
                recursionNoRepeat(s, index+1);
                swap(s, index, i);
            }
        }
    }
    
    public static void main(String[] args) {
        char[] s = new char[] {'1', '1', '3'};
        new Permutation().recursionNoRepeat(s, 0);
    }
去除重复,但是输出的顺序没有按字典序排序

(3)非递归

思路同 【LeetCode】31. Next Permutation

参考 https://blog.csdn.net/morewindows/article/details/7370155

 

posted @ 2019-03-16 10:48  chsobin  阅读(144)  评论(0编辑  收藏  举报