记我的第一次视频面试
来源:互联网 发布:linux 图形界面 编辑:程序博客网 时间:2024/04/28 08:13
最近参加一个据说是创业公司的视频面试,其中波折趣味一言难尽,在此分享一下我做的两道算法类题目。这是其中一道,初看这道题时,第一感觉是只要考虑每个数的个位即可,因为只有个位上的乘法才有可能产生0,于是乎好办了,每隔10个数能产生一个10的倍数,个位上的1……9又能产生一个0,于是只要算出有多少个10即可,每隔十个数能产生2个0,再看看m%10是否大于5,如果大于5,也能产生一个0,好,问题似乎是解决了,有点想当然了,写程序验证,验证当m = 20正确;m = 25时,按照我的算法,结果应该是2 * 25/10 + 1 = 5,但是看了一下,25!结尾是有6个0,不对,哪出了问题了呢?原来在于25这里,25可以分解为5*5,而20后的21,22,23,24,25这五个数的个位为:1,2,3,4,5,只能产生1个0,但是21,22,23,24,25这五个数相乘是能产生两个0的,原因就在于25这里,5*5,,原来,0的产生其实是跟5有关的,从1开始,每隔5个数,能产生一个0,因为每隔5个数,就能产生一个因子5,比如1……5,有一个5,6……10,10=2 * 5,那是不是结果就是m/5呢,还是不行,当m=25时还是不对,这是怎么回事?因为到25这里,产生了2个5,那125是5*5*5,625 = 5*5*5*5,要把这些情况都考虑进去才对,也就是每隔5的一个幂次级,就多产生一个5,比如到25这里,要多一个5,也就是说每隔25,就多产生一个5(如50,75,100),也就会多产生一个0,125这里又会多产生一个0……这下问题理清楚了,可以写程序了。
int count = 0;for (int i = 5; i <= m; i *= 5){count += m / i;}这道题的时间复杂度为Log5(m),看起来也挺靠谱的,像是一个算法的时间复杂度,嘿嘿,验证也无误。写程序也就是这么一点点,但是想的过程却是曲曲折折的,简约而不简单。
再来看看另外一道,我认为更难了。
也就是比如一个3行5列矩阵:
1 2 3 4 5 1 1 1
1 2 3 4 5 => 2 2 2
1 2 3 4 5 3 3 3
4 4 4
5 5 5
在一维数组中是按照[1 2 3 4 5 1 2 3 4 5 1 2 3 4 5]存的,现在要将它转置,那么它在数组中应该是:[1 1 1 2 2 2 3 3 3 4 4 4 5 5 5],当年到这道时,真是有点犯难,按以前求二维数组的矩阵来转置得了,多省事,非得弄这么一茬,不好弄了,想了好久没什么进展,直到最后才发现了一点点眉目:不是要转置么,我一个一个移,先将原矩阵的第0(按照C语言中的习惯,从0开始)列的第1个1保存,然后将它之前的5,4,3,2后移一位,再将1插入到数组的第1个位置,一维数组变成:11 2 3 4 5 2 3 4 5 1 2 3 4 5,按这个方法,移另个一个1,数组变成:1 1 12 3 4 5 2 3 4 5
2 3 4 5,好了,转置后的第一行完成了,原来当我进行移位的时候,数组中的其它元素的相对位置是不变的。再看数组中,因为1 已经排好序,不用管了,剩下3组2 3 4 5 ,怎么办呢,对了,把2 3 4 5 2 3 4 5 2 3 4 5 当成是一个新3的行4列矩阵,像刚才一样进行移位变换,于是数组变成:1 1 1 2 2 2 3 4 5 3 4 5 3 4 5,好了, 1、2都排好序了,剩下3组3 4 5 3 4 5 3 4 5,依此类推,结果就出来了。于是我们可以看到,对于m*n行的矩阵,把转置分为n - 1轮,每轮过后就会完成一列的转置,当完成n-1轮后,原矩阵已经有n-1列完成了转置,最后列由于算法的设计,自动转置了。按照这个算法,交换的次数就要多了,但是可以实现空间复杂度为O(1),也算是满足要求了。想起来有点点复杂,贴程序,用Python写的:
#-*-coding:utf8-*- #a:数组,m:行,n:列 def fun(a,m,n): #这个运算需要进行的次数 for c in range(n - 1):#表示[0,n-1) #每次的起始位置 frm = c * m for i in range(1,m): '''''下一个要确定位置的元素位置,并保存其值, 每次运算过后 ,剩下的元素组成的的m行数组列数减1 ''' pos = i * (n - c) + frm temp = a[pos] #pos的前n-1个数整体前移一位 for j in range(pos - 1,frm + i -1,-1): a[j + 1] = a[j] #找到位置并赋值 a[frm + i] = temp #测试 a = [1,1,1,1,1,2,2,2,2,2,3,3,3,3,3] b = [1,1,2,2,3,3,4,4,5,5,6,6,7,7] c = [1,1,1,2,2,2,3,3,3] fun(a,3,5) fun(b,7,2) fun(c,3,3) print a,'\n',b,'\n',c
这个算法想的时候很不顺利,写程序的时候到也有点小小的波折,所以想记录自己在解这两道题的时候思维过程,通过建立清晰的思维模型,严谨的分析与验证,才能得出正确的答案,在解题的过程中,如何想的真的很重要,它反映了我平时的一些不好的思维习惯,这些习惯定势还有很多地方需要改进。其实在视频面试的时候由于网络不太好,我完全有机会作弊,但是我知道,当看到答案时那一声惊呼:“原来是这样“,对我来说没有任何作用,只有自己慢慢想出来的经历了这个思维过程,至少对自己是有用的,还好,面试那人比较耐心,也比较相信我,嘿嘿
- 记我的第一次视频面试
- 记我的第一次面试
- 我的第一次面试
- 我的第一次面试
- 我的第一次面试
- 我的第一次面试
- 我的第一次面试
- 我的第一次面试,一塌糊涂
- 记录我的第一次面试
- 我的第一次CTO面试
- 我的第一次面试准备工作
- 我的第一次电话面试
- 我的第一次面试经历
- 说说我的第一次面试
- 记我第一次前端面试
- 记我的第一次Java开发工程师面试
- 我的传智第一次面试总结
- 第一次面试,加我的小吐槽
- 王远轩:北美求职记
- smarty设置参数
- stem算法
- IE10 平台预览版和 CSS 自适应布局功能
- git 常用命令
- 记我的第一次视频面试
- Use SWT to create browser application
- smarty中变量调节器
- JAVA和数据库高性能软件开发 实践培训课程 第1课
- 一段小小的C++代码(从保存H.264运动矢量过程中想到的)
- smarty中加载配置文件和运用循环
- (转自:ArthurChen)iphone开发之轻松搞定原生socket 编程,阻塞与非阻塞,收发自如
- MfC 进度条控件
- java7 NIO2(5) 文件和目录操作API