全排列

作者: 无聊的学习中 | 来源:发表于2016-07-17 01:28 被阅读0次

发现一直以来我写全排列的方法似乎有点山寨,2333
正规点的应该是,对于序列a[i..m],第i个地方的的值可以是a[i..m]中的任意一个,于是枚举k = i..m,
然后交换a[i], a[k],然后递归下去

void perm(int a[], int l, int r) {
    if (l == r) {
        for (int i = 0; i < r; i++) {
            printf("%d ", a[i]);
        }
        printf("\n");
        return ;
    }
    for (int i = l; i < r; i++) {
        swap(a[l], a[i]);
        perm(a, l + 1, r);
        swap(a[l], a[i]);
    }
}

简单的说i位置的元素就是剩下的元素里面选一个嘛,没啥问题。

然后呢,如果有重复元素咋办呢?按照我以前的山寨写法就要去重了,按内存开销可大了。
其实很简单,对于a[i]我们在剩下的里面选,重复的只选一次不就行了!所以呢,每次选的时候我们判断一下当前选的a[k],在a[i..k-1]里面是否出现过,如果出现过,说明a[i]这个位置我们已经选过a[k]这个值了,不用再重复选择了。

bool check(int a[], int l, int r) {
    for (int i = l; i < r; i++) {
        if (a[i] == a[r]) {
            return false;
        }
    }
    return true;
}
void perm(int a[], int l, int r) {
    if (l == r) {
        for (int i = 0; i < r; i++) {
            printf("%d ", a[i]);
        }
        printf("\n");
        return ;
    }
    for (int i = l; i < r; i++) {
        if (!check(a, l, i)) {
            continue;
        }
        swap(a[l], a[i]);
        perm(a, l + 1, r);
        swap(a[l], a[i]);
    }
}

相关文章

  • 全排列与字典序

    全排列 递归实现全排列; 首先来说递归算法实现全排列: 例如,对于{1,2,3,4}的例子进行全排列,其可以分解...

  • 全排列

    求全排列最简单的就是递归了123 的全排列共有 6 个, 123 的全排列等于以 1 开头 23 的全排列, 加上...

  • 全排列

    题目 输入一个字符串,按字典序打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a,b,c所能排...

  • 全排列

    递归的版本image.png

  • 全排列

  • 全排列

  • 全排列

    给出一个列表[1,2,3],其全排列为: [[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,...

  • 全排列

    给定一个数字列表,返回其所有可能的排列。

  • 全排列

    给定一个没有重复数字的序列,返回其所有可能的全排列。 示例: 输入: [1,2,3]输出:[[1,2,3],[1,...

  • 全排列

    两种方法:第一种方法:递归: 从集合中依次选出每一个元素,作为排列的第一个元素,然后对剩余的元素进行全排列,如此递...

网友评论

      本文标题:全排列

      本文链接:https://www.haomeiwen.com/subject/oqiujttx.html