版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u014485485/article/details/82532130
商汤科技的笔试题。n阶,步长1~m,有时间和内存限制。
基础题:
n阶楼梯,每次能走1或2阶,问走到n阶一共多少种走法。
法一:递归 很容易超时
f(0)=1,f(1)=1,f(n)=f(n-1)+f(n-2)
#include <stdio.h>
#include <iostream>
#include<Windows.h>
using namespace std;
long long climbStairs(int n)
{
if (n == 1)
return 1;
else if (n == 2)
return 2;
else if (n > 2)
return climbStairs(n - 1) + climbStairs(n - 2);
}
int main()
{
long long stepCount = 0;
DWORD start_time = GetTickCount();
stepCount = climbStairs(45); //40: 165580141 4.88s 45: 1836311903 53.99s
DWORD end_time = GetTickCount();
printf("%lld\n", stepCount);
cout << "The run time is: " << (end_time - start_time) / 1000.0 << " s!" << endl;
getchar();
return 0;
}
法二:递推 用空间换时间,避免了重复计算,时间快了很多倍
#include <stdio.h>
#include <iostream>
#include<Windows.h>
using namespace std;
long long step[101] = { 0 };
long long climbStairs(long long step[], int n)
{
if (n <= 0)
return 0;
step[0] = 1;//人为规定
step[1] = 1;
if (n >= 2)
{
for (long long i = 2; i <= n; i++)
{
step[i] = step[i - 1] + step[i - 2];
}
}
return step[n];
}
int main()
{
long long stepCount = 0;
DWORD start_time = GetTickCount();
stepCount = climbStairs(step, 40);
DWORD end_time = GetTickCount();
printf("%lld\n", stepCount);
cout << "The run time is: " << (end_time - start_time) / 1000.0 << " s!" << endl;
getchar();
return 0;
}
法三:找数学规律 类似于递推 求得通项 [Xn Xn-1]=[Xn-1+Xn-2;Xn-1]=...=[1 1;1 0]^(n-1) * [1 1]
#include <stdio.h>
#include <iostream>
#include<Windows.h>
using namespace std;
long long climbStairs(int n)
{
int a11 = 1, a12 = 1, a21 = 1, a22 = 0;
int v1 = 1, v2 = 1;
int x1 = 1, x2 = 1;
for (int i = 1; i < n; i++)
{
x1 = a11*v1 + a12*v2;
x2 = a12*v1 + a22*v2;
v1 = x1;
v2 = x2;
}
return v1;
}
int main()
{
long long stepCount = 0;
DWORD start_time = GetTickCount();
stepCount = climbStairs(40);
DWORD end_time = GetTickCount();
printf("%lld\n", stepCount);
cout << "The run time is: " << (end_time - start_time) / 1000.0 << " s!" << endl;
getchar();
return 0;
}
拓展:N阶台阶,每次可以走1~m步
法一:递归 时间容易超
#include <stdio.h>
#include <iostream>
#include<Windows.h>
using namespace std;
long long climbStairs(int n, int m) {
int stepsCount = 0;
if (n == 0) {
return 1;
}
if (n >= m) {// 总剩余的台阶数n大于步长m
for (int i = 1; i <= m; i++) {
stepsCount += climbStairs(n - i, m);
}
}
else {// 剩余台阶数n小于步长m
stepsCount += climbStairs(n, n);
}
return stepsCount;
}
int main()
{
long long stepCount = 0;
DWORD start_time = GetTickCount();
stepCount = climbStairs(45,2);//40:165580141 14.898s 45:1836311903 166s
DWORD end_time = GetTickCount();
printf("%lld\n", stepCount);
cout << "The run time is: " << (end_time - start_time) / 1000.0 << " s!" << endl;
getchar();
return 0;
}
上面这个代码太初级,只能解决n和m都很小的情况,通过了50%。题目中实际要求时间<=2s。
需要优化。待更新。