好久去过九度了,前两天去看了下,发现新出来了个面试题库,抽空做了下,题目都比较基础,附个简单的解题报告如下:
给个链接先:九度面试题
1. 二维数组中的查找
详细报告请移步:报告
2. 重建二叉树
给出二叉树的前序遍历和中序遍历,求后序遍历。
已知中序遍历,又知道前序或者后序遍历,则可以构造出该二叉树,唯一。
由前/后序遍历可知根的位置,再由中序对应子树位置,递归即解。
在读数的时候顺便取了最小值即可。或者二分也行,区别是可能最小值会在2个区间而不是一个。
4.斐波那契数列
注意long long型,没什么好说的。
5.跳台阶
4的变种。
6.变态跳台阶
递推方程:f[n] = f[n-1]+f[n-2]+...+f[0]。
7.矩形覆盖
4的变种。
8.顺时针打印矩阵
经典题目,模拟边界left,right,top,down,模拟每次走一圈即可。
9.栈的压入压出
经典问题,2栈顶相等时出栈,不等时压栈,直到栈空或者数据压完。
10.二叉搜索树的后序遍历序列
由于是二叉搜索树,sort后即中序遍历,其余类似题二
11.二叉树中和为某一值的路径
搜索即可,遍历所有root到leaf,为key则输出路径即可。
12.字符串的排序
sort和next_permutation简单应用。
经典问题。
先排序,若存在超过一半的数字,那么必然是array[mid],二分查到array[mid]的个数看它是否>n/2即可。
也可以排序后在顺序统计一下看有没有那个数字个数超过一半。
如果必然有超过一半的数字,即满足该数字的次数>n/2,则有O(N)的算法,因为该数字的次数超过一半,所以我们顺序扫描该序列,每次删掉当前不相同的两个数字,显然最后留下来的必然是超过一半的。
14.最小的K个数
由于要将最小的k个数从小到大输出,故sort即可。
若不用排序,则类似快排O(N)可解。
15.最大子向量和
即最大连续子序列和,dp。
16.整数中1出现的次数
如1111,出现了4个1。
这里可以用状态机去匹配,由于只用计算1的个数,直接统计最简单。
dp[i]记为0到10^i-1中所有数字中1的总和。
则dp[i] = dp[i-1]*10+10^(i-1) (dp[0]=0)。
然后在对每一位(从高到低)算即可。
17.所有员工年龄排序
由于年龄值>=0&&<=99,故计数排序即可。O(N)
18.丑数
经典问题,一个数只能被2,3,5整除的数记为丑数。求第k个丑数,1为第1个丑数。
则丑数=2^i*3^j*5^k。
枚举i,j,k即可,最后sort一下即可。
记个数即可。
20.数组中的逆序对
经典问题,在归并排序中,加入一个计数即可。O(nlogn)
由于数组已经排序,二分查找即可。map算会MLE。
22.二叉树的深度
求给定二叉树的深度,遍历一遍所有叶子即可。
23.数组中只出现一次的数字
set算,记当前为数字k,若set中有k了,则erase,否则insert,最后set中的数记为答案。
如果仅有一个数字只出现一次,那么所有异或出来的就是结果。
当有2个只出现一次,其他的都出现2次的时候,如果能够分成2个组,每个组都是由一个只出现一次的数字和若干个出现2次的数字组成,那么问题就轻易解决了。所有值异或起来得到k,显然k!= 0,故k至少有一个1,取最高为1的位为条件分割成2个数组,显然将分成2个奇数个数字的组,否则该位异或起来等于0,并且显然每个组满足上述要求,在分组的时候异或一次即可。
24.和为S的两个数字
顺序扫描,二分查找即可。
25.和为S的连续正数序列
求所有连续整数和为S,记i+(i+1)+..+j=s,由公式记首相为st,尾数为end,则(st+end)*(end-st+1)/2=s,枚举st,求end,看其是否是整数即可。
然而st最大可到s/2,效率太低。。。O(N)
记(i+1)+..+(i+j)=s,则i*j+j*(j+1)/2=s.即j*(i*2+j+1)=2*s
枚举j,显然j<=sqrt(2*s),且2*s%j==0时,j才能是一个候选解。
如此枚举,效率O(sqrt(n))
26.翻转单词顺序
翻转即可,注意空格什么的原封不动的保留下来输出。
经典问题,旋转。3个reverse即可。
28.乐透之猜数游戏
概率问题,求最大的3个概率及其对应的值。
记:x1+x2+..+xn = k ( n <= k <= n*m ) 有f[n][k]种不同的解。
则其概率为f[n][k]/m^n
显然f[n][k] = f[n][k-1] + f[n][k-2] + .. + f[n][k-m] (注意边界)
最后注意由于精确到小数点后2位,故f[n][k]不同,但最后f[n][k]/m^n的近似值可能是相同的,在排序前先取好近似值,后在排序,取值可先+0.005,*100,去int省略小数后再/100即可。
29.扑克牌顺子
有一个字符能够匹配任意字符,问给定的是否能成顺子。
注意有相同的也不行。连续两个差1,多的补通配符即可。
经典问题,约瑟夫问题,逆向考虑。
解为 for( i = 1 , x = 0 ; i <= n ; i++) x=(x+m)%i
以上都是简单分析,如有不清楚或者错误的地方请留言。