程序员面试题精选100题的答案合集和一些常用算法

最近在为找工作做些准备,做了些题看了些算法,其中有一个程序员面试题精选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算法(见上一篇博文)

发表评论?

6 条评论。

  1. 看了你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/,感兴趣的话可以看看。欢迎探讨 :razz:

    • 非常感謝你指出的问题,我没有考虑到如果字符串連续相等的话回文的中心是会动的,已经更正。顺便还删除了不必要的循环和一个内存泄漏。那个blog是你的吗?感觉很不错 :razz:

      • 是的,我是你说的163博客的博主。我看了一下你的代码,结果应该是正确的。在细节处仍然有可以改进的地方:比如数组lens实际上是没有必要的(也就是空间复杂度可以降低到O(1))。l==0的那个if语句似乎也不是必须的。我更新了一下博客,http://zhedahht.blog.163.com/blog/static/25411174201063105120425/。里面参考了你的思路,非常感谢。

        • 你说的很对哈,之前只想着实现没想着最优解。。见笑了。。

          • 仔细测试了一下,如果输入”ababa”或者”baabaa”,得到的结果都不正确。看来我们还需要更加仔细的分析……

          • 尴尬了- -,我再想想 。。。反正再不济有后缀数组顶着。。

发表评论


注意 - 你可以用以下 HTML tags and attributes:
<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>