1. <?php
    2. class Solution {
    3. /**
    4. * @param Integer[] $nums
    5. * @return array
    6. */
    7. function nextPermutation(&$nums) {
    8. if (!$nums || count($nums) == 1) {
    9. return $nums;
    10. }
    11. // 从右往左,找到第一个逆序元素 $reverse
    12. $reverse = count($nums) - 1;
    13. for ($i = $reverse; $i > 0; $i--) {
    14. if ($nums[$i] > $nums[$i - 1]) {
    15. $reverse = $i - 1;
    16. break;
    17. }
    18. }
    19. // 从右往左,找到大于 $reverse 且 最接近 $reverse 的元素 $close
    20. if (($close = $reverse + 1) < (count($nums) - 1)) {
    21. for ($j = $reverse + 1; $j < count($nums); $j++) {
    22. if ($nums[$j] < $nums[$reverse]) {
    23. continue;
    24. }
    25. $close = ($nums[$j] - $nums[$reverse]) < ($nums[$close] - $nums[$reverse]) ? $j : $close;
    26. }
    27. }
    28. // 交换 $reverse 和 $close
    29. $tmp = $nums[$reverse];
    30. $nums[$reverse] = $nums[$close];
    31. $nums[$close] = $tmp;
    32. // 翻转 $reverse 右边的元素
    33. $tmp1 = array_slice($nums, 0, $reverse + 1);
    34. $tmp2 = array_reverse(array_slice($nums, $reverse + 1));
    35. $nums = array_merge($tmp1, $tmp2);
    36. return $nums;
    37. }
    38. }
    39. /**
    40. * 1,2,3 → 1,3,2
    41. * 3,2,1 → 1,2,3
    42. * 1,1,5 → 1,5,1
    43. *
    44. * 1,5,8,4,7,6,5,3,1 → 1,5,8,4,7,6,5,3,1
    45. * 1,5,8,4,7,6,5,3,1 → 1,5,8,5,7,6,4,3,1
    46. * 1,5,8,5,7,6,4,3,1 → 1,5,8,5,1,3,4,6,7
    47. */
    48. $nums = [1,5,8,4,7,6,5,3,1];
    49. $cls = new Solution();
    50. $ret = $cls->nextPermutation($nums);
    51. echo implode(',', $ret);