首页 > 代码库 > [LeetCode]31 Next Permutation
[LeetCode]31 Next Permutation
https://oj.leetcode.com/problems/next-permutation/
http://fisherlei.blogspot.com/2012/12/leetcode-next-permutation.html
public class Solution { public void nextPermutation(int[] num) { // Solution B nextPermutation_Math(num); // Solution A // nextPermutation_AllPerms(num); } /////////////////////////////////////// // Solution A: Generate all permutations for num // Sort it // Find the next one. public void nextPermutation_AllPerms(int[] num) { // All perms List<List<Integer>> allperms = new ArrayList<>(); allperms(num, 0, allperms); // Sort Collections.sort(allperms, new Comparator<List<Integer>>() { public int compare(List<Integer> a, List<Integer> b) { int len = a.size(); for (int i = 0 ; i < len ; i ++) { if (a.get(i) != b.get(i)) { return Integer.compare(a.get(i), b.get(i)); } } return 0; } }); // Find int pos = allperms.indexOf(listof(num)); pos = (pos + 1) % allperms.size(); for (int i = 0 ; i < num.length ; i ++) { num[i] = allperms.get(pos).get(i); } } // See Permutations II private void allperms(int[] n, int start, List<List<Integer>> result) { int len = n.length; if (start >= len) { // A result found. result.add(listof(n)); } for (int i = start ; i < len ; i ++) { // If we have any dups from start to i. // No need to continue recursion // // 注意不要误以为以下两种做法能够去重: // (1)最开始先对数组进行排序,以后每次交换时,只要保证当前要交换的元素和前一个元素不同,这种做法是错误的. // 虽然开始进行了排序,但是元素的交换会使数组再次变的无序 // (2)每次进入递归函数permuteRecur时,对从当前索引开始的子数组排序,这种做法也是错误的. // 因为每次交换元素后,我们要恢复交换的元素,如果在递归函数内排序,就不能正确的恢复交换的元素。 if (unique(n, start, i)) // if (n[start] != n[i]) { swap(n, i, start); allperms(n, start + 1, result); swap(n, i, start); } } } private boolean unique(int[] n, int start, int end) { for (int i = start ; i < end ; i ++) { if (n[i] == n[end]) return false; } return true; } /////////////////////////////////////// // Solution B: A math // I don‘t know why // public void nextPermutation_Math(int[] num) { if (num == null || num.length <= 1) return; // No need continue // Step 1, search from right to left. // Find the first index break increase. // // Step 2, search from right to left // Find the first index with value > firstindex. // // Step 3, swap firstindex and secondindex // // Step 4, reverse all elements after first index. // Step 1 int firstindex = -1; int len = num.length; for (int i = len - 1 ; i > 0 ; i --) { if (num[i - 1] < num[i]) { firstindex = i - 1; break; } } if (firstindex == -1) { // All decrease. // Reverse all reverse(num, 0); return; } // Step 2 int secondindex = num.length - 1; while (secondindex > firstindex) { if (num[secondindex] > num[firstindex]) break; secondindex --; } if (secondindex == firstindex) return; // invalid // Step 3 swap(num, firstindex, secondindex); // Step 4 reverse(num, firstindex + 1); } ///////////////////////////////////// // // Tools // Reverse num from s(inclusive) to the end private void reverse(int[] num, int s) { int i = s; int j = num.length - 1; while (i < j) { swap(num, i, j); i ++; j --; } } private void swap(int[] num, int i , int j) { int t = num[i]; num[i] = num[j]; num[j] = t; } private List<Integer> listof(int[] n) { List<Integer> toReturn = new ArrayList<>(n.length); for (int i : n) toReturn.add(i); return toReturn; } }
[LeetCode]31 Next Permutation
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。