下一次最近排列

对序列 {a, b, c},每一个元素都比后面的小,按照字典序列,固定a之后,a比bc都小,c比b大,它的下一个序列即为{a, c, b},而{a, c, b}的上一个序列即为{a, b, c},同理可以推出所有的六个序列为:{a, b, c}、{a, c, b}、{b, a, c}、{b, c, a}、{c, a, b}、{c, b, a},其中{a, b, c}没有上一个元素,{c, b, a}没有下一个元素。

代码如下:

void swap(int *a, int *b)
{
    int c = *a;
    *a = *b;
    *b = c;
}
void reverse(int *array, int begin, int end)
{
    int i, j;
    for (i = begin, j = end; i < j; i++, j--)
    {
        swap(&array[i], &array[j]);
    }
}

int next_permutation(int *array, int begin, int end)
{
    if (array == NULL || begin >= end)
    {
        return 0;
    }
    int i, j, k;
    for (j = end, i = end - 1; i >= begin && j > begin; j--, i--)
    {
        if (array[i] < array[j])
        {
            break;
        }
    }
    if (j == 0 && i == -1)
    {
        return 0;
    }

    for (k = end; k >= j; k--)
    {
        if (array[k] > array[i])
        {
            break;
        }
    }
    swap(&array[i], &array[k]);
    reverse(array, i + 1, end);
    return 1;
}

int main(void)
{
    int array[4] = {1, 2, 3, 4};
    int begin = 0, end = 3;
    do
    {
        int i;
        for (i = 0; i <= end; i++)
        {
            cout << array[i] << ", ";
        }
        cout << endl;
    }while (next_permutation(array, begin, end));
    getchar();
    return 0;
}

运行结果:

下一次最近排列

时间: 2024-10-07 07:22:07

下一次最近排列的相关文章

js工作常见问题收集

1. viewport <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=no" /> // width 设置viewport宽度,为一个正整数,或字符串'device-width' // device-width 设备宽度 // height 设置viewport高度,

回形排列

题目      在n*n方阵里放入1,2,3,4.............,n*n,要求填成蛇形. 例如n=4时方阵为 1     2     3     4 12   13    14    5 11   16    15    6 10    9    8     7 解析 如图 在第一行里 行数不变,列数依次加一,即第一行数为(1,1)(1,2)(1,3)........(1,n) 在第一行排列完以后,到第n列,在进行竖着排 即列数不变,行数依次加一,即第一行数为(n,1)(n,2)(n,

排列组合递归和非递归算法总结篇

#include <iostream> #include <string> #include <math.h> #include <vector> #include <algorithm> using namespace std; //method1 bool flag[5] ; int arr[5] = {1,2,3,4,5}; int len = sizeof(arr)/sizeof(int); void Comb(int n,int cou

Josephus排列

思考与分析: 对于m为常数,可以用循环链表,用head,tail标志头尾指针使其易于表示循环结构.循环输出后删除结点n次,每次外层循环时,内层都固定循环m次.所以运行时间为O(mn)=O(n). 对于m为非常数.可以用顺序统计树,用size属性记录每个结点在当前树中所在的位置.经过一个取余过程,每次都能正确找到并输出删除每个结点,在经过n次循环,每次循环都要找到一个结点输出并删除它,所以每次循环都要花费O(lgn)时间.总的运行时间是O(nlgn). 代码如下: m为常数时: #include

排列组合(permutation)系列解题报告

本文讲解4道关于permutation的题目: 1. Permutation:输出permutation--基础递归 2. Permutation Sequence: 输出字典序排列的第k个permutation--推理3. Next Permutation:给定一个permutation中的序列,求字典序它的下一个permutation是什么--逻辑推理4. Permutation II:和第一题有细微的差别: 对于一个可能有重复元素的数组输出所有permutation--有条件dfs    

从排列到组合——深度优先搜索

前段时间在洛谷3.0上刷到一个题,让本人挠头了一段时间,RT: 题目描述 已知 n 个整数 x1,x2,-,xn,以及一个整数 k(k<n).从 n 个整数中任选 k 个整数相加,可分别得到一系列的和.例如当 n=4,k=3,4 个整数分别为 3,7,12,19 时,可得全部的组合与它们的和为: 3+7+12=22  3+7+19=29  7+12+19=38  3+12+19=34. 现在,要求你计算出和为素数共有多少种. 例如上例,只有一种的和为素数:3+7+19=29. 首先解决这个问题显

打印给定字符串中字符的所有排列

题目: 输入一个字符串,打印出该字符串中字符的所有排列.例如输入字符串abc,则输出由字符a.b.c所能排列出来的所有字符串abc.acb.bac.bca.cab和cba. 解决: 简单起见,字符串中没有相同的字符. 其实这是个递归的过程:对于字符串str,先分别逮住其中的每一个,如s,把它从str中踢开,成了 s + tr(下一次踢开t变为 t + sr),然后对于剩下来的,再从剩下的再次分别踢开一个加到左边的后面(假想被踢开的都在左边,剩下的都在右边哈),一直如此,直至右边都踢光了.算法如下

ACM 擅长排列的小明

擅长排列的小明 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 小明十分聪明,而且十分擅长排列计算.比如给小明一个数字5,他能立刻给出1-5按字典序的全排列,如果你想为难他,在这5个数字中选出几个数字让他继续全排列,那么你就错了,他同样的很擅长.现在需要你写一个程序来验证擅长排列的小明到底对不对. 输入 第一行输入整数N(1<N<10)表示多少组测试数据,每组测试数据第一行两个整数 n m (1<n<9,0<m<=n) 输出 在1-n中选取

概率论1 计数-排列-组合

作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! 概率 概率论研究随机事件.它源于赌徒的研究.赌博中有许多随机事件,比如投掷一个骰子,是否只凭运气呢? 赌徒逐渐发现随机事件的规律.投掷两个骰子是常见的赌博游戏.如果重复很多次,那么总数为2的次数会比总数7的次数少.这就是赌徒把握到的规律:尽管我无法预知事件的具体结果,但我可以了解每种结果出现的可能性.这是概率论的核心. "概率"到底是什么?这在数学上还有争议."