https://leetcode-cn.com/problems/next-permutation/

    1. class Solution {
    2. public void nextPermutation(int[] nums) {
    3. // 思路:从后向前,找到升序子序列,然后调整子序列的最高位,剩余部分升序排列
    4. int length = nums.length;
    5. // 0. 从后向前,找到升序子序列,找到第一次下降的数,位置记为 k
    6. int k = length - 2;
    7. while (k >= 0 && nums[k] >= nums[k + 1]) {
    8. k--;
    9. }
    10. // 1. 找到目标 k,需要调整部分的最高位
    11. // 2. 特殊情况,k = -1
    12. if (k == -1) {
    13. reverse(nums, 0, length - 1);
    14. return;
    15. }
    16. // 3. 一般情况,k >= 0
    17. // 3.1 依次遍历剩余降序部分,找到替换最高位的那个数
    18. // 其是小于 k 的那个数的前一位
    19. int i = k + 2;
    20. while (i < length && nums[i] > nums[k]) {
    21. i++;
    22. }
    23. // 3.2 i - 1 就是需要替换的数字,交换 i - 1 和 k 的数值
    24. swap(nums, k, i - 1);
    25. // 3.3 k 下标之后的所有数升序排列,因为前面操作之后,还是一个降序序列,
    26. // 所以可以使用 双指针交替替换
    27. reverse(nums, k + 1, length - 1);
    28. }
    29. private void swap(int[] nums, int k, int i) {
    30. // 交换操作封装函数
    31. int temp = nums[k];
    32. nums[k] = nums[i];
    33. nums[i] = temp;
    34. }
    35. private void reverse(int[] nums, int start, int end) {
    36. // 翻转数组封装函数
    37. while (start < end) {
    38. swap(nums, start, end);
    39. start++;
    40. end--;
    41. }
    42. }
    43. }

    image.png

    1. class Solution {
    2. private static void swapMy(int[] nums, int i, int j) {
    3. int temp = nums[i];
    4. nums[i] = nums[j];
    5. nums[j] = temp;
    6. }
    7. private static void fanzhuan(int[] nums, int start, int end) {
    8. while (start < end) {
    9. swapMy(nums, start, end);
    10. start++;
    11. end--;
    12. }
    13. }
    14. public void nextPermutation(int[] nums) {
    15. int tar = nums.length - 2;
    16. while (tar >= 0 && nums[tar] >= nums[tar + 1]) {
    17. tar--;
    18. }
    19. if (tar == -1) {
    20. fanzhuan(nums, 0, nums.length - 1);
    21. return;
    22. }
    23. int res = tar + 2;
    24. while (res < nums.length && nums[tar] < nums[res]) {
    25. res++;
    26. }
    27. swapMy(nums, tar, res - 1);
    28. // 剩下直接反转
    29. fanzhuan(nums, tar + 1, nums.length - 1);
    30. }
    31. }