程序员面试题100题(一)

题目选自以下博客网址:
http://zhedahht.blog.163.com/#。

第26题:
题目:输入一个正数n,输出所有和为n连续正数序列。

例如输入15,由于1+2+3+4+5=4+5+6=7+8=15,所以输出3个连续序列1-5、4-6和7-8。

分析:这是网易的一道面试题。

我自己的思路:
首先想到的是等差数列的求和,即(m1+(m1+k-1))*k=n*2,  其中起始数字start=m1,结束数字end=m1+k-1;
因此这道题目的解和n*2的因子有关,解的集合在2n的在 [2,sqrt(2n)] 区间的几个因子相关。每个因子可能对应一个解,但是也可能这个因子没有解。

int imax=(int)Math.Sqrt(n*2)+1;
for(int i=2; i<imax;i++)
{
    if((n*2)%i==0)
    {
        //我们找到了i是2n的一个因子
        temp=n*2 - i*i + i;
        if( temp%(i*2)==0)
        {
            //我们发现这个因子确实是一个解
            start=temp/(i*2);
            end=start+ i -1;
            Console.WriteLine("{0}-{1}", start,end);
        }
    }
}

当n=30000时,输出结果如下:

9999-10001
5998-6002
1993-2007
1188-1212
922-953
363-437
265-360
178-302
108-267

我觉得它的好处是代码量较少,清晰易读。

————————————————————————————————————————
第23题:跳台阶问题
题目:一个台阶总共有n级,如果一次可以跳1级,也可以跳2级。求总共有多少总跳法,并分析算法的时间复杂度。

分析:这道题最近经常出现,包括MicroStrategy等比较重视算法的公司都曾先后选用过个这道题作为面试题或者笔试题。

首先我们考虑最简单的情况。如果只有1级台阶,那显然只有一种跳法。如果有2级台阶,那就有两种跳的方法了:一种是分两次跳,每次跳1级;另外一种就是一次跳2级。

现在我们再来讨论一般情况。我们把n级台阶时的跳法看成是n的函数,记为f(n)。当n>2时,第一次跳的时候就有两种不同的选择:一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1);另外一种选择是第一次跳2级,此时跳法数目等于后面剩下的n-2级台阶的跳法数目,即为f(n-2)。因此n级台阶时的不同跳法的总数f(n)=f(n-1)+(f-2)。

我们把上面的分析用一个公式总结如下:

        /  1                          n=1
f(n)=      2                          n=2
        \  f(n-1)+(f-2)               n>2

分析到这里,相信很多人都能看出这就是我们熟悉的Fibonacci序列。

问题的解,是一个树形结构,我引入了TreeView中的节点TreeNode来成生这个树,它是一个典型递归:

//组装一个根节点成为一颗树
    static void AddNode(System.Windows.Forms.TreeNode root,int n)
    {
        if(n>2)
        {
            root.Nodes.Add("1");
            root.Nodes.Add("2");
            AddNode(root.Nodes[0],n-1);
            AddNode(root.Nodes[1],n-2);
            
        }
        else if(n==1)
        {
            root.Nodes.Add("1");
        }
        else if(n==2)
        {
            root.Nodes.Add("1");
            root.Nodes[0].Nodes.Add("1");
            
            root.Nodes.Add("2");
        }
    }

树组装好以后,每一个叶子节点的全路径就是一个解,因此将叶子节点的FullPath(路径)打印出来即为一个解,这里为了找到叶子节点,也是使用递归:

//打印出所有叶子节点的全路径
static void PrintNode(TreeNode node)
{
    //属于叶子节点!!!!则打印这个路径
    if(node.Nodes.Count==0)
        Console.WriteLine(node.FullPath);
    else
    {
        foreach(TreeNode child in node.Nodes)
        {
            PrintNode(child);
        }
    }
}

当输入n=5时,打印出所有叶子节点的FullPath如下:

root\1\1\1\1\1
root\1\1\1\2
root\1\1\2\1
root\1\2\1\1
root\1\2\2
root\2\1\1\1
root\2\1\2
root\2\2\1

我们可以把一个解在一个TreeView里面完整显示出来:

递归算法有一个很受限制的地方,它占用栈空间以深度的级数速度增长,如果深度太大,会迅速达到空间上限。因此只适合较浅深度求解。

时间: 2024-09-25 05:10:31

程序员面试题100题(一)的相关文章

[程序员面试题精选100题]9.链表中倒数第k个结点

题目 输入一个单向链表,输出该链表中倒数第k个结点.链表的倒数第0个结点为链表的尾指针. 思路一 因为是单向链表,只有从前往后的指针而没有从后往前的指针.因此我们不能倒序遍历链表,只能正序遍历.假设整个链表有n个结点,那么倒数第k个结点是从头结点开始的第n-k-1个结点(从0开始计数).我们只需要得到链表中结点的个数n,那我们只要从头结点开始往后走n-k-1步就可以了. 因此这种方法需要遍历链表两次.第一次得到链表中结点个数n,第二次得到从头结点开始的第n-k-1个结点即倒数第k个结点.时间复杂

[程序员面试题精选100题]1.把二叉查找树转变成排序的双向链表

[题目] 输入一棵二叉查找树,将该二叉查找树转换成一个排序的双向链表.要求不能创建任何新的结点,只调整指针的指向. 比如将二叉查找树                                            10                                          /    \                                        6       14                                      / 

[程序员面试题精选100题]50.树的子结构

题目 输入两棵二叉树A和B,判断树B是不是A的子结构. 例如,下图中的两棵树A和B,由于A中有一部分子树的结构和B是一样的,因此B就是A的子结构. 思路 这是2010年微软校园招聘时的一道题目.二叉树一直是微软面试题中经常出现的数据结构.对微软有兴趣的读者一定要重点关注二叉树. 回到这个题目的本身.要查找树A中是否存在和树B结构一样的子树,我们可以分为两步: (1)树A中找到和B的根结点的值一样的结点N (2)再判断树A中以N为根结点的子树是不是包括和树B一样的结构. 第一步在树A中查找与根结点

[程序员面试题精选100题]58.八皇后问题

题目 在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行.同一列或者同一对角斜线上.下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法.请求出总共有多少种摆法. 思路 这就是有名的八皇后问题.解决这个问题通常需要用递归,而递归对编程能力的要求比较高.因此有不少面试官青睐这个题目,用来考察应聘者的分析复杂问题的能力以及编程的能力. 由于八个皇后的任意两个不能处在同一行,那么这肯定是每一个皇后占据一行.于是我们可以定义一个数组colIndex[8],colI

[程序员面试题精选100题]6.二叉查找树的后序遍历结果

[题目] 输入一个整数数组,判断该数组是不是某二叉查找树的后序遍历的结果.如果是返回true,否则返回false. 例如输入5.7.6.9.11.10.8,由于这一整数序列是如下树的后序遍历结果:           8         /    \       6    10      /   \   /   \    5    7 9 11 因此返回true. 如果输入7.4.6.5,没有哪棵树的后序遍历的结果是这个序列,因此返回false. [分析] 这是一道trilogy的笔试题,主要考

[程序员面试题精选100题]12.从上往下遍历二叉树

[题目] 输入一颗二元树,从上往下按层打印树的每个结点,同一层中按照从左往右的顺序打印. 例如输入         8      /      \     6     10    /   \     /  \   5  7   9  11 输出8   6   10   5   7   9   11 [分析] 这曾是微软的一道面试题.这道题实质上是要求遍历一棵二元树,只不过不是我们熟悉的前序.中序或者后序遍历. 我们从树的根结点开始分析.自然先应该打印根结点8,同时为了下次能够打印8的两个子结点,

[程序员面试题精选100题]13.第一个只出现一次的字符

[题目] 在一个字符串中找到第一个只出现一次的字符.如输入abaccdeff,则输出b. [分析] [代码] /********************************* * 日期:2013-12-23 * 作者:SJF0115 * 题目: 13.第一个只出现一次的字符 * 来源:微软 * 分类:程序员面试题精选100题 **********************************/ #include <iostream> #include <cstring> us

Java程序员面试题集(86-115)

Java程序员面试题集(86-115) 摘要:下面的内容包括Struts 2和Hibernate的常见面试题,虽然Struts 2在2013年6月曝出高危漏洞后已经显得江河日下,而Spring MVC的异军突起更加加速了Struts 2的陨落,但面试中仍然有可能被问及和此框架相关的内容,毕竟Struts 2曾经被阿里巴巴.京东以及政府企业门户网站广泛采用.另一方面,Hibernate目前仍然是ORM框架中的中坚力量,MyBatis在此领域也有不容忽视的一席之地,因此了解这两个ORM框架对Java

[程序员面试题精选100 题]17.把字符串转换成整数

题目 输入一个表示整数的字符串,把该字符串转换成整数并输出.例如输入字符串"345",则输出整数345. 分析 这道题尽管不是很难,学过 C/C++语言一般都能实现基本功能,但不同程序员就这道题写出的代码有很大区别,可以说这道题能够很好地反应出程序员的思维和编程习惯,因此已经被包括微软在内的多家公司用作面试题.建议读者在往下看之前自己先编写代码,再比较自己写的代码和下面的参考代码有哪些不同. 我们需要考虑一下几个方面的问题: (1)正负问题: 由于整数可能不仅仅之含有数字,还有可能以'