【LeetCode】31. Next Permutation
【题目】
将给定的元素进行全排列,给定一个排列,求基于字典序进行排序的下一个排列
eg: 1,2,3
→ 1,3,2
3,2,1
→ 1,2,3
1,1,5
→ 1,5,1
【思路】贴上官方题解图
【代码】
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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 }
【拓展】
打印全排列的三种方法
(1)递归打印
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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)递归打印非重复
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
// 检查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