一、题意
实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。
1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1
二、解题
解题思路
字典序:从右往左,找到第一个左值小于右值的数,然后从右往左,找到第一个大于该左值的数,交换这两个值,并将该左值(不包含)右边的进行从小到大进行排序(原来为降序,只需要改为升序)。结合下图理解
代码实现
class Solution {
/**
* @param Integer[] $nums
* @return NULL
*/
function nextPermutation(&$nums) {
$n = count($nums);
for ($i = $n - 2; $i >= 0; $i--) {
if ($nums[$i + 1] > $nums[$i]) {
for ($j = $n - 1; $j >= 0; $j--) {
if ($nums[$j] > $nums[$i]) {
break;
}
}
$temp = $nums[$i];
$nums[$i] = $nums[$j];
$nums[$j] = $temp;
$left = $i + 1;
$right = $n - 1;
return $this->reverse($nums, $left, $right);
}
}
return $this->reverse($nums, 0, $n - 1);
}
//反转函数
function reverse(&$nums, $left, $right) {
while ($left < $right) {
$temp = $nums[$left];
$nums[$left] = $nums[$right];
$nums[$right] = $temp;
$left++;
$right--;
}
}
}
还不快抢沙发