力扣 全排列-46
全排列-46
class Solution {//搜索与回溯
public:
vector<vector<int>> res;//存储所有排列结果
int cnt[10];//存储当前排列的数字
int vis[10];//标记数组,标记每个元素是否被使用过,使用过就标记为1
void dfs(vector<int>& nums,int depth)
{
vector<int>vec;
if(depth>nums.size())//终止条件
{
for(int i=1;i<=nums.size();i++)
{
vec.push_back(cnt[i]);//将当前排列一次,排列好的元素加入到vec中
}
res.push_back(vec);//将每次排列之后的结果加入二维数组res中
return;//结束递归
}
for(int i=0;i<nums.size();i++)
{
if(!vis[i])//没有被使用过的情况下
{
vis[i]=1;//将当前元素标记为1,被使用过
cnt[depth]=nums[i];//将当前元素加入排列数组中
dfs(nums,depth+1);//递归下一个深度
vis[i]=0;//回溯,标记nums[i]没有被使用
}
}
}
public:
vector<vector<int>> permute(vector<int>& nums) {
dfs(nums,1);//
return res;
}
};
每日问题
什么是函数重载? 函数重载的实现原理是什么?
什么是函数重载?
函数重载(Function Overloading)是指在同一个作用域中,多个函数可以拥有相同的名字,但它们的参数列表(参数的个数或类型)不同。通过参数的不同,编译器可以区分调用哪个重载版本的函数。
函数重载的示例:
#include<iostream>
using namespace std;
void print(int x) {
cout << "Integer: " << x << endl;
}
void print(double x) {
cout << "Double: " << x << endl;
}
int main() {
print(10); // 调用 print(int)
print(3.14); // 调用 print(double)
return 0;
}
在上面的例子中,print 函数根据传入的参数类型调用不同的重载版本。
函数重载的实现原理
函数重载的实现原理主要涉及编译器如何区分不同版本的函数。编译器依靠函数签名(function signature)来确定调用哪个函数,函数签名由以下几个部分组成:
- 函数名(Function Name)
- 参数列表(Parameter List),包括参数的类型、个数和顺序(注意,返回值类型不参与函数签名的区分)
编译器如何区分重载的函数?
1.参数的类型、个数和顺序:
如果两个或多个函数的参数类型、个数或顺序不同,编译器就可以通过这些差异来区分它们。
比如:
void print(int)
void print(double)
void print(int, double)
2.默认参数值:
默认参数值不能用于区分函数重载。即使你给函数添加了默认参数,编译器仍然会认为函数重载是基于参数列表来区分的。
重载解析过程:
1.函数的名字:编译器首先通过函数的名字来寻找对应的函数。
2.匹配参数类型:编译器接着会根据函数调用时传递的参数类型,寻找最匹配的重载函数。
3.候选函数的确定:编译器会生成一系列“候选函数”,然后通过参数匹配来选出最适合的一个。如果没有找到一个完全匹配的函数,编译器可能会尝试进行类型转换(比如将 int 转换为 float 或 double)来匹配一个重载版本。
举例说明:
假设有以下重载函数:
void foo(int a) { cout << "int: " << a << endl; }
void foo(double a) { cout << "double: " << a << endl; }
void foo(int a, double b) { cout << "int and double: " << a << ", " << b << endl; }
调用:
foo(10); // 调用 foo(int)
foo(3.14); // 调用 foo(double)
foo(10, 3.14); // 调用 foo(int, double)
如果你传递的参数类型没有找到完全匹配的函数,编译器会选择最接近的函数,并进行类型转换。例如:
foo(10.5); // 编译器会将 10.5 转换为 double,调用 foo(double)
总结:
- 函数重载是指在同一个作用域中定义多个同名但参数列表不同的函数。
- 编译器通过函数签名(包括函数名和参数类型)来区分不同版本的函数。
- 返回值类型不参与函数重载的区分。