全排列是蓝桥杯中的高频考点之一,接下来为我的学习历程:
先练习基本的全排列 -> 熟练应用后套用stl函数库->进阶练习
1、全排列 - 基础练习
2、全排列 ll - 进阶练习
3、C++模板函数套用
4、排列序数(蓝桥真题)
5、带分数(蓝桥真题)
给定一个不含重复数字的数组
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;
}
};
给定一个可包含重复数字的序列
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;
}
};
在竞赛中,如果使用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
题目描述
如果用 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<
带分数
题目描述
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()));
*/
--------------------------------------------------------
按照以上可基本掌握基础的全排列,方便进阶学习。
如有错误,私信我,定及时更改。