最近去上海爱立信面试,原本以为像一般公司正常流程一样,直接上手一份笔试题,答完,再进行技术面。没想到是反过来的,先进行英文面,而后技术面,结束了,再直接就是下文这道笔试题,要求在半小时内完成。
面试中的具体过程,这就不多说了,直接说说这道笔试题吧。
题目如图所示,有m*n个格子,从第一个格子,走到最后一个格子,中间过程,只能向右或向下移动,需一格一格前进,问这样走,有多少条路径?要求说出解题思路并写出伪代码,即可,限时半小时。
这道题看似很简单,其实真正去做的话,还是有点难度的。
这里说一下,我的解题思路及代码验证,当然,如有大神,有更精妙的办法,也求分享~
大致思路:
假设m为4, n为3,(1,1)点为起点,(4,3)为终点,路径走法:
先向右走到底然后向下走
(1,1)->(2,1)->(3,1)->(4,1)->(4,2)->(4,3)
由于向右走到了底,向下时,已没有其他选择。
而后是,重新从起点出发,先从(1,1)向右走到最后第二格,然后开始向下,有如下几种情况:
(1,1)->(2,1)->(3,1)->(3,2)->(4,2)->(4,3)
(1,1)->(2,1)->(3,1)->(3,2)->(3,3)->(4,3)
而后是,重新从起点出发,先从(1,1)向右走到最后第三格,然后开始向下,有如下几种情况:
(1,1)->(2,1)->(2,2)->(3,2)->(4,2)->(4,3)
(1,1)->(2,1)->(2,2)->(3,2)->(3,3)->(4,3)
(1,1)->(2,1)->(2,2)->(2,3)->(3,3)->(4,3)
依次类推,我的原则就是能向右的就先向右走,如果之前重复了,就pass掉,换另外的路走,这样可以保证每个格子都刷到,路径数量就能保证,不会出现漏掉的情况。
代码实现上,我采用了递归的做法,具体代码如下:
#include <stdio.h>
#include <stdlib.h>
static int sum = 0; //路径总数
static int m = 0; //m代码横排格子数目
static int n = 0; //n代表竖排格子数目
void searchPathNum(int DownNum, int RightNum)
{
if(RightNum == m)//到最右边了
{
if(DownNum == n)//到最下边了
{
sum++;
}
else
{
//继续向下走一步
searchPathNum((DownNum + 1), RightNum);
}
return;
}
if(DownNum == n)//到最下边了
{
if(RightNum == m)//到最右边了
{
sum++;
}
else
{
//继续向右走一步
searchPathNum(DownNum, (RightNum + 1));
}
return;
}
//向右走一步
if(RightNum < m)
{
searchPathNum(DownNum, (RightNum + 1));
}
//向下走一步
if(DownNum < n)
{
searchPathNum((DownNum + 1), RightNum);
}
}
void main()
{
m = 0;
n = 0;
printf("input m and n: For example 3,3\n");
scanf("%d,%d", &m, &n);
//从(1,1)起点开始走
searchPathNum(1, 1);
printf("sum = %d\n", sum);
system("PAUSE");
}
代码粗略分析:
从(1,1)起点出发,优先向右走,不断进行递归, 就能按照之前思路分析那样,走相应的路径了。个人觉得,这代码算法效率上,应该不咋滴~但是苦恼,始终没想出妙招。
执行情况截图: