题意:
在所有不同的组合数中,求出第小的组合数。
解法一(暴力枚举,set判重,不可AC)
我们首先观察杨辉三角的一部分
我们可以直接枚举出杨辉三角中行中的所有数字,然后利用set数据结构来进行判重,最后返回set中第个数字即可。
具体的:
我们已知,故对于第行,我们只需要枚举第个数字即可
代码:
class Solution { public: unordered_map<int,int> fac;//记忆化搜索,存储n!的值 int get_fac(int n){//计算阶乘 if(n==0)return 1; if(fac.find(n)!=fac.end())return fac[n]; //return fac[n]=n*get_fac(n-1); //如果爆int了直接返回0 int t=get_fac(n-1); if(t==0||INT_MAX/t<n)return fac[n]=0; return fac[n]=t*n; } int C(int n,int m){//组合数 int x=get_fac(n); if(x<=0)return 0;//如果爆int了,直接返回0 //n! 不会爆int,下面肯定不会爆int int y=get_fac(m); x/=y; y=get_fac(n-m); x/=y; return x; } int kthSamllest(int k) { set<int> s; for(int i=0;i<=k;i++){ for(int j=0;j<=i/2;j++){//根据C(i,j)=C(i,i-j),故只需要枚举到一半即可 int x=C(i,j); if(x==0)continue; s.insert(x); } } return *s.lower_bound(k);//返回第k个数字 } };时间复杂度:,我们枚举组合数的代价是的,计算组合数由于我们计算阶乘使用了记忆化搜索,故均摊下来是的,set单次插入和查询都是的,故总的时间复杂度为
空间复杂度:,我们set中需要存储级别个数的数字,中需要存储个数字用于保存阶乘值,故总的空间复杂度为
解法二(数学分析)
我们知道,而由于组合数都是整数,故第小的数字即为
所以直接返回即可
代码:
class Solution { public: int kthSamllest(int k) { return k; } };时间复杂度:,我们直接返回答案,故时间复杂度为
空间复杂度:,程序中我们只用到了一个整型变量,故空间复杂度为