技术面,草草的问了一些经历以后出了三个题。
1.10000000个数据中取前1000大。
经典的取前K大问题,使用hash+快排partition 。以四字节unsigned int为例,num[65536]数组用来标记unsigned int数的前两个字节出现的次数。遍历一次数组,记录num[65536]。在num数组中取前K大,这样可以得到第K大数字的前两个字节记做temp。接下来重置num数组,再标记unsinged int数的后两个字节出现的次数。第二次遍历数组,遇到前两个字节大于temp的值,直接输出,小于temp的略过,等于temp的,根据后两个字节的数据标记num数组。第二次遍历结束,可以取出第K大数据。然后输出temp<<16+oxFFFF num[0xFFFF]次,接着往下输出,知道第K大数。
2.N!末尾0的个数
此问题直接等于求N中5的因子个数,解法如下:
N/5 + N/25 + N/125......
求等比数列和的问题,直接可以导出公式。
3.给定一个字符串,求取其中所有的数字子串
char
**
find_num(
char
*
src)
...
{
char* now = src;
char** result;
int i = -1, j;
char flag = 0;
result = malloc(50 * sizeof(char*));
memset(result, 0, 50 * sizeof(char*));
while(*now) ...{
if(*now > '9' || *now < '0') flag = 0;
else ...{
if(flag) ...{
result[i][j++] = *now;
} else ...{
j = 0;
result[++i] = malloc(50 * sizeof(char));
memset(result[i], 0, 50 * sizeof(char));
result[i][j++] = *now;
flag = 1;
}
}
*now++;
}
return result;
}
char* now = src;
char** result;
int i = -1, j;
char flag = 0;
result = malloc(50 * sizeof(char*));
memset(result, 0, 50 * sizeof(char*));
while(*now) ...{
if(*now > '9' || *now < '0') flag = 0;
else ...{
if(flag) ...{
result[i][j++] = *now;
} else ...{
j = 0;
result[++i] = malloc(50 * sizeof(char));
memset(result[i], 0, 50 * sizeof(char));
result[i][j++] = *now;
flag = 1;
}
}
*now++;
}
return result;
}
据说还有一些问题如下:
1.如何实现malloc,free函数
2.01背包
3.3分钟写快排、10分钟写二叉排序树、10分钟堆排序之类的
还好我今天没遇到,不然以我一年多没碰算法的基础,直接死悄悄了。不过今天面的也不是很顺利,前两个当时有点进小巷了,没想出来。
在此感谢saga同学提供的hash思路。