数组表示数的下一个比它大的最小的置换

本文介绍了一个经典的算法问题——实现下一个排列。该问题要求在给定的一组数字中找到字典序上比当前更大的下一个排列,并且必须在原地进行替换。文章详细解释了算法的实现过程,包括如何通过双指针技巧定位需要交换的位置,以及如何调整数组以得到正确的下一个排列。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Implement next permutation, which rearranges numbers into the lexicographically next greater permutation of numbers.

 

If such arrangement is not possible, it must rearrange it as the lowest possible order (ie, sorted in ascending order).

 

The replacement must be in-place, do not allocate extra memory.

 

Here are some examples. Inputs are in the left-hand column and its corresponding outputs are in the right-hand column.

1,2,3 1,3,2

3,2,1 1,2,3

1,1,5 1,5,1

 

题解:

从后往前遍历,设置一个preaft,指针

 

int comp ( const void*a, const void *b )

{

    return *( int *) a - * (int *) b;

}

 

int get_next(int *array, int len)

{

    assert(array!= NULL &&len >= 0);

    

    int * pre = array + len -2;    //指向数组倒数第2个数

    int * aft = pre + 1;           //指向数组最后一个数

    int index = len - 1;           //置换的第一个数的下标 index 等于0时表示这个数是最大数,因为没有找到前一个比后一个小的数。

    while((pre -array) >= 0&& (aft -array) > 0&& (pre <aft) )

    {

        if(*pre >= *aft ) // 略过前一个数比后一个数大的

        {

            pre--;

            aft--;

        }

        else    //找到前一个比后一个小的数

        {

            int * p = pre;  //找到最后还要回退比较找到pre aft之后的数是否有比它大的 比如1 2 3 4 6 8 7 3 2 1 当前pre指向6aft 指向8            

            int *q = aft +1;

            int flag =0;

            while(*p!= '\0')

            {

                if(*p< *q )

                {

                    flag= 1;

                    break;

                }

                p++;

                q++;

            } 

 

            if(flag ==1)

            {

                int tmp =*q;

                *q = *pre;

                *pre = tmp;

            }

            else

            {

                int tmp =*aft;

                *aft = *pre;

                *pre = tmp;

            }

            qsort(aft,len- aft, sizeof(int),comp);

            break;

       }

        index--;

    }

 

    if(index ==0)

    {

         qsort(array,len, sizeof(int), comp);

    }

    

    return index;

}

 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值