提示:本题是系列LeetCode的150道高频题,你未来遇到的互联网大厂的笔试和面试考题,基本都是从这上面改编而来的题目
互联网大厂们在公司养了一大批ACM竞赛的大佬们,吃完饭就是设计考题,然后去考应聘人员,你要做的就是学基础树结构与算法,然后打通任督二脉,以应对波云诡谲的大厂笔试面试题!
你要是不扎实学习数据结构与算法,好好动手手撕代码,锻炼解题能力,你可能会在笔试面试过程中,连题目都看不懂!比如华为,字节啥的,足够让你读不懂题
示例:看上面
这题,挺恶心的,当时看我朋友测试案例就只能过50%
很巧……我怀疑后台测试案例有问题
否则怎么巧了1/2概率对呢
n个树,任选k个树活着
因为是至少k个,所以可能k+1个活着呢
k+2活着呢
又或者就是n个全活了
所以就是连加
结果它代码50%过,不懂为啥????
手撕代码
public static class Main2{
//gcd(a,b)的公式,我们早讲过无数次,死记硬背:b=0,返回a,否辗转相处求gcd(b,a%b)
public static long gcd(long a, long b){
return b == 0 ? a : gcd(b, a % b);
}
//正式用gcd来月C(n,k)的分子分母,防止溢出,计算C(n,k)
public static int Cnk(int n, int k){
long a = 1;//分母
long b = 1;//分子//上面说了哦,分母a从n-k+1开始到n连成阶乘//分子b从1--k连成阶乘//a/b在循环时将gcd约了//i帮着分母循环,j帮着分子循环
for (int i = n - k + 1, j = 1; i <= n || j <= k; i++, j++) {
//当i或者j越界了也没事,因为ab,最终会约的
a *= i;
b *= j;//分母分子轮番乘自己的阶乘//然后约
long gcd = gcd(a, b);
a /= gcd;
b /= gcd;
}
return (int) (a / b);
}
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int t = in.nextInt();
for (int i = 0; i < t; i++) {
int n = in.nextInt();
int k = in.nextInt();
int ans = 0;
for (int j = k; j <= n; j++) {
ans += Cnk(n, j);
}
System.out.println(ans);
}
}
}
dp是n+1乘n+1的格子
i行代表0–i个树里面随意挑树
挑j个活着(必须活着)
(0)dp[0][0]=1,为啥,从0个树里面选j=0个树活着,就是不选,方法为1种
(1)0行,全是0,为啥呢,没有树,你不可能选j个活着啊
(2)0列,全是1,为啥呢,有树,但是只能选j=0个活着,就是不选,方案1种
(4)剩下的dpij任意格子怎么求?
很简单,只看i位置的树活着,还是死了?
i活着的话,那从0–i-1范围上只需要选j-1根树活着(拢共就j个活着呗)
i死了的话,那从0–i-1范围上必须得选j根树活着(拢共就j个活着呗)
这两种情况加起来就是dpij
手撕代码:
public static class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int mod = (int) (1e9+7);
int t = in.nextInt();
for (int x = 0; x < t; x++) {//t次
int n = in.nextInt();
int k = in.nextInt();
int[][] dp = new int[n + 1][n + 1];//从0--i行选j个树活着
dp[0][0] = 1;//0棵树范围上选0活着,方法就一种,不选
//0行,其他默认0,只有0棵树,就不可能有j=1以上的树活着
for (int i = 1; i <= n; i++) {//现在只填0列
dp[i][0] = 1;//树必死
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j] % mod;//i活着,i死了两种情况
}
}
int ans = 0;
for (int j = k; j <= n; j++) {
ans += dp[n][j];
}
System.out.println(ans);
}
}
}
测试:
输入
3
2 1
6 3
9 9
输出
3
42
1
很OK,就是不知道蔚来后台到底是怎么了,尴尬,只过了50%
2种方案都是,没道理啊,蔚来一直很坑,非常不爽
提示:重要经验:
1)动态规划,nk显然就是样本位置对应模型,整一个二维表即可,摸索很快就OK了
3)笔试求AC,可以不考虑空间复杂度,但是面试既要考虑时间复杂度最优,也要考虑空间复杂度最优。