Leetcode uma pergunta do dia: 31.next-permutation (next-permutation)

Insira a descrição da imagem aqui
A questão significa encontrar a próxima permutação maior da sequência numérica dada. Por exemplo, se dado 1,2,3, encontre o menor número entre os números maiores que 123, ou seja, 132, então sua permutação é 1,3,2;

Idéia: Se todos estão em ordem decrescente, então não deve haver ordem superior, então
passo 1: Deve ser para encontrar um par ascendente nele e, em seguida, trocar a posição do número grande e o número decimal, como 12843, trocar 2, 8 para obter 18243, mas se você trocar 1, 2, obterá 21.843, que é maior que 18243, então você tem que começar da direita Encontre o primeiro par em ordem crescente à esquerda ;
passo 2: O menor número maior que 12.843 de 18243 não é, porque este 8 também, obviamente 13842 é maior que 12843, mas menor que 18243, então precisamos de um número mínimo maior que 2 para encontrar o 2 correto, coloque-o com 2 trocas que é Mas, como 28 é o primeiro par em ordem crescente, os 2 seguintes devem estar em ordem decrescente, então você só precisa encontrar o menor número maior que 2 da direita para a esquerda e, em seguida, trocar, aqui você obtém 13842;
etapa 3: Após as duas etapas acima, encontramos o 13842, mas ainda é mínimo, porque mais de 12843 13248 13842 pequeno do que grande mas, então aqui identificado 13, vamos colocar tudo atrás do número 3 foi alterado para ordem ascendente tão certo, É o menor, porque o 3 está em ordem decrescente, então só precisamos virar para baixo, o
próximo algoritmo de arranjo é explicado em detalhes: ideia + derivação + passos, se você não entender, eu perco!
Insira a descrição da imagem aqui
Insira a descrição da imagem aqui

void nextPermutation(vector<int> &nums)
{
    
    
    int len = nums.size();
    if (len < 2)
    {
    
    
        return;
    }
    int i = len - 2, j = len - 1, k = len - 1;
    //step1:从后向前找到第一对升序对
    while (i >= 0 && nums[i] >= nums[j])
    {
    
    
        i--;
        j--;
    }
    if (i < 0) //如果整个数组都是降序,那么设j=0,后面逆置nums[j~end]
    {
    
    
        j = 0;
    }
    else //找到升序对
    {
    
    
        //step2:从后向前找到第一个大于nums[i]的最小的数(肯定能找到)
        while (k > i && nums[i] >= nums[k])
        {
    
    
            k--;
        }
        //交换nums[i]和nums[j]
        int temp = nums[i];
        nums[i] = nums[k];
        nums[k] = temp;
    }

    //step3:逆置nums[j~end]
    while (j < len - 1)
    {
    
    
        int temp = nums[j];
        nums[j] = nums[len - 1];
        nums[len - 1] = temp;
        j++;
        len--;
    }
}

Acho que você gosta

Origin blog.csdn.net/wyll19980812/article/details/109235586
Recomendado
Clasificación