import java.util.Arrays; public class NextPermutation { // 思路:从后向前找到升序子序列,然后确定调整后子序列的最高位,剩余部分升序排列 public void nextPermutation1(int[] nums){ int n = nums.length; // 1. 从后向前找到升序子序列,找到第一次下降的数,位置记为k int k = n - 2; while ( k >= 0 && nums[k] >= nums[k+1] ) k --; // 找到k,就是需要调整部分的最高位 // 2. 如果k = -1,说明所有数降序排列,改成升序排列 if ( k == -1 ){ Arrays.sort(nums); return; } // 3. 一般情况,k >= 0 // 3.1 依次遍历剩余降序排列的部分,找到要替换最高位的那个数 int i = k + 2; while ( i < n && nums[i] > nums[k] ) i ++; // 当前的i,就是后面部分第一个比nums[k]小的数,i-1就是要替换的那个数 // 3.2 交换i-1和k位置上的数 int temp = nums[k]; nums[k] = nums[i-1]; nums[i-1] = temp; // 3.3 k之后的剩余部分变成升序排列,直接前后调换 int start = k + 1; int end = n - 1; while ( start < end ){ int tmp = nums[start]; nums[start] = nums[end]; nums[end] = tmp; start ++; end --; } } // 方法改进:将降序数组翻转的操作提取出来 public void nextPermutation(int[] nums){ int n = nums.length; // 1. 从后向前找到升序子序列,找到第一次下降的数,位置记为k int k = n - 2; while ( k >= 0 && nums[k] >= nums[k+1] ) k --; // 找到k,就是需要调整部分的最高位 // 2. 如果k = -1,说明所有数降序排列,改成升序排列 if ( k == -1 ){ reverse(nums, 0, n - 1); return; } // 3. 一般情况,k >= 0 // 3.1 依次遍历剩余降序排列的部分,找到要替换最高位的那个数 int i = k + 2; while ( i < n && nums[i] > nums[k] ) i ++; // 当前的i,就是后面部分第一个比nums[k]小的数,i-1就是要替换的那个数 // 3.2 交换i-1和k位置上的数 swap(nums, k, i - 1); // 3.3 k之后的剩余部分变成升序排列,直接前后调换 reverse(nums, k + 1, n - 1); } // 定义一个方法,交换数组中两个元素 private void swap( int[] nums, int i, int j ){ int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } // 定义一个翻转数组的方法 private void reverse( int[] nums, int start, int end ){ while ( start < end ){ swap(nums, start, end); start ++; end --; } } public static void main(String[] args) { int[] nums = {1,3,2}; NextPermutation permutation = new NextPermutation(); permutation.nextPermutation(nums); for ( int num: nums ) System.out.print(num + "\t"); } }