一、题意

实现获取下一个排列的函数,算法需要将给定数字序列重新排列成字典序中下一个更大的排列。
如果不存在下一个更大的排列,则将数字重新排列成最小的排列(即升序排列)。
必须原地修改,只允许使用额外常数空间。
以下是一些例子,输入位于左侧列,其相应输出位于右侧列。

1,2,3 → 1,3,2
3,2,1 → 1,2,3
1,1,5 → 1,5,1

二、解题

解题思路

字典序:从右往左,找到第一个左值小于右值的数,然后从右往左,找到第一个大于该左值的数,交换这两个值,并将该左值(不包含)右边的进行从小到大进行排序(原来为降序,只需要改为升序)。结合下图理解

1df4ae7eb275ba4ab944521f99c84d782d17df804d5c15e249881bafcf106173-file_1555696082944.gif

代码实现

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--;
        }
    }
}

本文由 一切随风 创作,可自由转载、引用,但需署名作者且注明文章出处。

8 条评论

  1. vgowdzocic
    vgowdzocic

    谜案追凶1

  2. lixcpkrmcw
    lixcpkrmcw

    终极拦截

  3. xedsdidzno
    xedsdidzno

    金钱堡垒

  4. sosdlwqlck
    sosdlwqlck

    法国贩毒网2

  5. vgxsghaepq
    vgxsghaepq

    绝命银行

  6. pzsaikbfqb
    pzsaikbfqb

    寻凶

  7. zsbmyufuft
    zsbmyufuft

    武松斗杀西门庆

  8. zhsfdibggz
    zhsfdibggz

    《恋爱初歌》剧情片高清在线免费观看:https://www.jgz518.com/xingkong/50355.html

添加新评论