全排列(蓝桥必备1)

全排列是蓝桥杯中的高频考点之一,接下来为我的学习历程:

先练习基本的全排列 -> 熟练应用后套用stl函数库->进阶练习


1、全排列 - 基础练习

2、全排列 ll - 进阶练习

3、C++模板函数套用

4、排列序数(蓝桥真题)

5、带分数(蓝桥真题)


1、全排列 - 基础练习

给定一个不含重复数字的数组 nums ,返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。

示例 1:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

示例 2:

输入:nums = [0,1]
输出:[[0,1],[1,0]]

示例 3:

输入:nums = [1]
输出:[[1]]

提示:

  • 1 <= nums.length <= 6
  • -10 <= nums[i] <= 10
  • nums 中的所有整数 互不相同
// 本题格式是,力扣的独有格式。
// 本题通过递归进行,全排列
class Solution {

    // 各处存数据的数组
    vector> res;
    vector cur;
    void generate(vector& nums, vector& userd){
        
        if(cur.size()==nums.size()){
            res.push_back(cur);
            return;
        }    
        for(int i=0; i> permute(vector& nums) {
        res.clear();
        cur.clear();
        vector userd(nums.size(),false);
        generate(nums,userd);
        return res;
    }

};

2、全排列II - 基础练习

给定一个可包含重复数字的序列 nums ,按任意顺序 返回所有不重复的全排列。

示例 1:

输入:nums = [1,1,2]
输出:
[[1,1,2],
 [1,2,1],
 [2,1,1]]

示例 2:

输入:nums = [1,2,3]
输出:[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]

提示:

  • 1 <= nums.length <= 8
  • -10 <= nums[i] <= 10
class Solution {
public:
    vector> res;
    vector cur;
    void generate(vector& nums, vector& used){
        if(cur.size()==nums.size()){
            res.push_back(cur);
            return;
        }
        for(int i = 0; i0&&!used[i-1]&&nums[i]==nums[i-1]) continue; // 跳过是精华核心,每次递归到同一档次的时候,就直接跳过。
                used[i]=true;
                cur.push_back(nums[i]);
                generate(nums,used);
                cur.pop_back();
                used[i]=false;
            }
        }

    }
    vector> permuteUnique(vector& nums) {
        res.clear();
        cur.clear();
        sort(nums.begin(),nums.end()); // 排序是本题基础
        vector used(nums.size(),false);
        generate(nums,used);
        return res;
    }
};

3、C++模板函数套用

在竞赛中,如果使用dfs进行全排列的话,确实非常麻烦。固,可引用tls库中的内容。

共两种用法,主要:

1、next_permutation(vec.begin(), vec.end());

2、prev_permutation(vec.begin(), vec.end());

#include "bits/stdc++.h"
using namespace std;

vector> res;
vector cur;

void generate(vector& vec, vector& used){
    if(cur.size()==vec.size()){
        res.push_back(cur);
        return;
    }

    for(int i=0; i vec{1,2,3};

    // 全排列
    cout<<"------------ 以下是next_permutation生成与输出 ------------------"< used(vec.size(), false);
    generate(vec,used);

    for(vector& v : res){
        for(int num : v){
            cout<

 下方为输出函数:

------------ 以下是next_permutation生成与输出 ------------------
1 2 3 
1 3 2 
2 1 3 
2 3 1 
3 1 2 
3 2 1 
------------ 以下为手写DFS函数的输出 ------------------
1 2 3 
1 3 2 
2 1 3 
2 3 1 
3 1 2 
3 2 1 

4、排列序数(蓝桥真题)

题目描述

如果用 a b c d 这 4 个字母组成一个串,有 4!=24 种,如果把它们排个序,每个串都对应一个序号:

abcd 0

abdc 1

acbd 2

acdb 3

adbc 4

adcb 5

bacd 6

badc 7

bcad 8

bcda 9

bdac 10

bdca 11

cabd 12

cadb 13

cbad 14

cbda 15

cdab 16

cdba 17

⋯⋯

现在有不多于 10 个两两不同的小写字母,给出它们组成的串,你能求出该串在所有排列中的序号吗?

输入描述

输入一行,一个串。

输出描述

输出一行,一个整数,表示该串在其字母所有排列生成的串中的序号。注意:最小的序号是 0。

输入输出样例

示例

输入

bdca

输出

11

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 256M
#include "bits/stdc++.h"
using namespace std;
int main(){
    string str,strx;
    cin>>str;
    strx=str;
    sort(str.begin(),str.end());

    int ans=0;
    do {
        if(strx==str){
            break;
        }
        ans++;
    }while(next_permutation(str.begin(),str.end()));
    cout<

5、带分数 - 真题(蓝桥真题)

带分数

题目描述

100 可以表示为带分数的形式:100 = 3 + 69258 / 714

还可以表示为:100 = 82 + 3546 / 197

注意特征:带分数中,数字 1~9 分别出现且只出现一次(不包含 0 )。

类似这样的带分数,100 有 11 种表示法。

输入描述

从标准输入读入一个正整数 N (N<1000×1000)N (N<1000×1000)。

输出描述

程序输出该数字用数码 1~9 不重复不遗漏地组成带分数表示的全部种数。

注意:不要求输出每个表示,只统计有多少表示法!

输入输出样例

示例

输入

100

输出

11
#include 
#include 
#include 
using namespace std;

int generate(const vector& vec, int st, int en){
    int sum = 0;
    for(int i = st; i<=en; i++){ // 求和
        sum = sum*10 + vec[i];
    }
    return sum;
}

int main(){

    int num;
    cin >> num;
    vector vec{
            1,2,3,4,5,6,7,8,9
    };

    // 排列是什么
    // 分成三个点,分别对每个点
    vector num1;
    vector num2;
    vector num3;
    int n1,n2,n3;
    int flag = 0;
    do{ // 直接套三个循环会极其不合理。
        for(int i=0; i num1;
  vector num2;
  vector num3;
  int n1,n2,n3;
  int flag = 0;
  do{
    for(int i=0; inum) break;
      if((n1+n2/n3==num) flag++;
      }
    }

  }while(next_permutation(vec.begin(), vec.end()));
*/

--------------------------------------------------------

按照以上可基本掌握基础的全排列,方便进阶学习。

如有错误,私信我,定及时更改。


你可能感兴趣的:(算法,数据结构,全排列)