最近在为找工作做些准备,做了些题看了些算法,其中有一个程序员面试题精选100题好像是比较有名的(现在还没出满100题),我把自己的答案放上来,如果有人来讨论一下那更好了。我是用的C来做题,有些C++ only的题就跳过了。还有一些别的算法比如RMQ的st解法,kmp等代码都在里面。打包下载地址在这里jingxuan.tar.gz。
顺便有几个算法想单独地说一下:
1. O(n)时间求最长回文。主要思路就是从第一个字符开始扫描,记录下以当前字符结尾的最长回文长度。代码如下
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
int
find(const char *s)
{
if (!s)
return -1;
int lens = strlen(s);
int i, same = 1, pre = 1, max = 0;
for (i = 1; i < lens; i ++) {
int l = 0, s1;
s1 = i - pre - 1;
if (s1 >= 0 && *(s + s1) == *(s + i))
l = pre + 2;
if (l == 0)
l = *(s + i - 1) == *(s + i) ? 2 : 1;
if (*(s + i) == *(s + i - 1))
same += 1;
else
same = 1;
s1 = l > same ? l : same;
if (s1 > max)
max = s1;
pre = s1;
}
return max;
}
int
main(int argc, char **argv)
{
printf("%d\n", find("aaa"));
printf("%d\n", find("goooog"));
printf("%d\n", find("guouyy"));
return 0;
}
2. 怎么在O(n)的时间,O(1)的空间找出一串数字中两个不同的只出现一次的数字(别的都出现两次)。这题普遍一点的解法是用位数组,不过还可以考虑把整个数组分成两个子数组,每个分别含有一个只出现一次的数字。代码如下
#include <stdio.h>
#include <assert.h>
int n1, n2;
int
find_once(int array[], int length)
{
assert(length > 0);
assert(array != NULL);
int all = 0, pos = 0, i = 0;
unsigned int tmp;
for (i = 0; i < length; i ++)
all ^= array[i];
assert(all != 0);
tmp = (unsigned int)all;
pos = (tmp - (tmp & (tmp - 1)));
for (i = 0; i < length; i ++) {
if (array[i] & pos != 0)
n1 ^= array[i];
else
n2 ^= array[i];
}
return 0;
}
int
main(int argc, char **argv)
{
int a[10] = {1, 2, 1, 2, -1, -1, 3, 3, 0, -4};
find_once(a, 10);
printf("%d %d", n1, n2);
return 0;
}
3. 全排列、组合、幂集算法,分重复不重复两种情况(待添加)
4. 后缀数组(待添加)
5. kmp算法(见上一篇博文)
看了你O(n)时间找最长回文的代码,还有意思的思路。不过当我用测试用例printf(“%d\n”, find(“aaa”));和printf(“%d\n”, find(“ccccc”));结果不对。似乎代码中还有小问题。另外,这里有Python的代码,http://www.akalin.cx/2007/11/28/finding-the-longest-palindromic-substring-in-linear-time/,感兴趣的话可以看看。欢迎探讨
非常感謝你指出的问题,我没有考虑到如果字符串連续相等的话回文的中心是会动的,已经更正。顺便还删除了不必要的循环和一个内存泄漏。那个blog是你的吗?感觉很不错
是的,我是你说的163博客的博主。我看了一下你的代码,结果应该是正确的。在细节处仍然有可以改进的地方:比如数组lens实际上是没有必要的(也就是空间复杂度可以降低到O(1))。l==0的那个if语句似乎也不是必须的。我更新了一下博客,http://zhedahht.blog.163.com/blog/static/25411174201063105120425/。里面参考了你的思路,非常感谢。
你说的很对哈,之前只想着实现没想着最优解。。见笑了。。
仔细测试了一下,如果输入”ababa”或者”baabaa”,得到的结果都不正确。看来我们还需要更加仔细的分析……
尴尬了- -,我再想想 。。。反正再不济有后缀数组顶着。。