程序员面试题精选100题:41-50解题报告

原创 2013年06月25日 18:18:38

程序员面试题精选100题(41)-把数组排成最小的数[算法]  

题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。例如输入数组{32,  321},则输出这两个能排成的最小数字32132。请给出解决问题的算法,并证明该算法。

根据题目的要求,两个数字m和n排成的数字mn和nm,如果mn<nm,那么我们应该输出mn,也就是m应该排在n的前面,也就是m小于n;反之,如果nm<mn,n小于m。如果mn==mn,m等于n。

接下来我们考虑怎么去拼接数字,即给出数字m和n,怎么得到数字mn和nm并比较它们的大小。直接用数值去计算不难办到,但需要考虑到的一个潜在问题是m和n都在int能表达的范围内,但把它们拼起来的数字mn和nm就不一定能用int表示了。所以我们需要解决大数问题。一个非常直观的方法就是把数字转换成字符串。

 

===========================================================================

程序员面试题精选100题(42)-旋转数组的最小元素[算法]  

题目:把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个排好序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3, 4, 5, 1, 2}为{1, 2, 3, 4, 5}的一个旋转,该数组的最小值为1。

分析:遍历可以获得最小元素,所以考察的复杂度肯定小于O(n),那基本只有O(logn)了,那就是折半查找了。怎么利用折半呢?

判断l-mid是否递增(a[l]<=a[mid]),如果是那么结果在右边,l=mid+1;否则还在左边,迭代或者递归。

终止条件是l=r.

特殊情况a[l]<=a[r],直接返回a[l]。。。

 

扩展:

===========================================================================

程序员面试题精选100题(43)-n个骰子的点数[算法]  

题目:把n个骰子扔在地上,所有骰子朝上一面的点数之和为S。输入n,打印出S的所有可能的值出现的概率。

分析:递推关系:f(n,s)=sum(f(n-1,s-k))*1/6,1<=k<=6

初始f(0,0)=1,f(0,1….6n)=0;0<=s<=6n

结果:f(n,n….6n)

我不知道这个叫不叫动态规划哦,不过和动态规划是一个路子。

空间优化:可以使用滚动数组优化为只用一个数组存储,没必要使用n维存储,s从右向左。

 

直接递归会重复计算,也可以使用记忆递归避免重复。

===========================================================================

程序员面试题精选100题(44)-数值的整数次方[算法]  

题目:实现函数double Power(double base, int exponent),求base的exponent次方。不需要考虑溢出。

坑不少呐,负数,除零,,,,而且还可以分治二分优化。。。。。

===========================================================================

程序员面试题精选100题(45)-Singleton(C/C++/C#)  

题目:设计一个类,我们只能生成该类的一个实例。

分析:只能生成一个实例的类是实现了Singleton模式的类型。

我们只需要在最开始调用Singleton4_getInstance(可能来自一个线程,也可能来自多个线程)的时候需要加锁。当实例已经创建之后,我们就不再需要作加锁操作,从而在后续调用Singleton4_getInstance时性能得到提升。

 

http://blog.csdn.net/nanjunxiao/article/details/8974639

===========================================================================

程序员面试题精选100题(46)-对称子字符串的最大长度[算法]  

题目:输入一个字符串,输出该字符串中对称的子字符串的最大长度。比如输入字符串“google”,由于该字符串里最长的对称子字符串是“goog”,因此输出4。

分析:O(n^3)的能想到,O(n^2)的O(n)的没想到。。。智商拙计

O(n^2)以每个字符为中心,向两边扩展,判断是否为回文,O(n),n个中心所以复杂度为O(n^2)。

相对于暴力O(n^3),减少了两端中间是否回文的判断,肯定是回文的。

O(n)的后缀树,不会,找个时间看看。。。

===========================================================================

程序员面试题精选100题(47)-数组中出现次数超过一半的数字[算法]  

题目:数组中有一个数字出现的次数超过了数组长度的一半,找出这个数字。

分析:1.hash

2.血拼。。。最后剩下的就是。

===========================================================================

程序员面试题精选100题(48)-二叉树两结点的最低共同父结点[数据结构]  

输入二叉树中的两个结点,输出这两个结点在数中最低的共同父结点。

第一变种是二叉树是一种特殊的二叉树:查找二叉树。也就是树是排序过的,位于左子树上的结点都比父结点小,而位于右子树的结点都比父结点大。我们只需要从根结点开始和两个结点进行比较。如果当前结点的值比两个结点都大,则最低的共同父结点一定在当前结点的左子树中。如果当前结点的值比两个结点都小,则最低的共同父结点一定在当前结点的右子树中。

第二个变种是树不一定是二叉树,每个结点都有一个指针指向它的父结点。于是我们可以从任何一个结点出发,得到一个到达树根结点的单向链表。因此这个问题转换为两个单向链表的第一个公共结点。我们在本面试题系列的第35讨论了这个问题。

现在我们回到这个问题本身。所谓共同的父结点,就是两个结点都出现在这个结点的子树中。因此我们可以定义一函数,来判断一个结点的子树中是不是包含了另外一个结点。这不是件很难的事,我们可以用递归的方法来实现:

这种会重复计算。接着我们来分析一下这个方法的效率。函数HasNode的本质就是遍历一棵树,其时间复杂度是O(n)(n是树中结点的数目)。由于我们根结点开始,要对每个结点调用函数HasNode。因此总的时间复杂度是O(n2)。

我的想法是先序递归遍历,每个节点存储从根到该节点的路径,只需递归一次,最终找到两个节点,两个路径最后一个相等的即为结果。但明显空间使用较多。

答案给出了一种方法,但需要递归两遍来找到两个节点,同时得到路径。。。

===========================================================================

程序员面试题精选100题(49)-复杂链表的复制[算法]  

 下图是一个含有5个结点的该类型复杂链表。图中实线箭头表示m_pNext指针,虚线箭头表示m_pSibling指针。为简单起见,指向NULL的指针没有画出。

                  

                

请完成函数ComplexNode* Clone(ComplexNode* pHead),以复制一个复杂链表。

 

维护一个hash_map <N,N’>方便定位subing,O(n)复杂度

答案没看。。。。

===========================================================================

程序员面试题精选100题(50)-树的子结构[数据结构]  

输入两棵二叉树A和B,判断树B是不是A的子结构。

例如,下图中的两棵树A和B,由于A中有一部分子树的结构和B是一样的,因此B就是A的子结构。

                1                                                  8
              /   \                                               /   \
             8    7                                            9    2
            /   \
          9    2
               /  \
              4  7

 

递归:

Booldigui(Tree* A,Tree* B)

{

         If(NULL == B)

                   Return true;

         If(NULL == A)

                   Return false;

         If(A->data == B->data)

         {

                   Return digui(A->l,B->l)&& digui(A->r,B->r);

}

Else

{

         Return digui(A->l,B)|| digui(A->r,B);

}

}

没问题吧,不用答案的那种先递归找到相同根节点,在递归判断是否相同子树。。。。两个递归揉到一个递归里了。。。

程序员面试题精选100题-何海涛

  • 2015年02月08日 17:00
  • 906KB
  • 下载

程序员面试题精选100题

今天开始各种刷面试题,沉下心来集中时间,全身心投入 (01)-把二元查找树转变成排序的双向链表[数据结构]      题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求...
  • tianqiangxfyang
  • tianqiangxfyang
  • 2013-09-09 21:43:19
  • 818

程序员面试题精选100题完整版

  • 2017年08月09日 09:40
  • 957KB
  • 下载

程序员面试题精选100题(自己整理)

  • 2008年11月19日 16:19
  • 536KB
  • 下载

程序员面试题精选100题:51-63解题报告

程序员面试题精选100题(51)-顺时针打印矩阵[算法]   题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。 例如:如果输入如下矩阵: 1              2  ...
  • nanjunxiao
  • nanjunxiao
  • 2013-06-26 00:07:09
  • 1184

程序员面试题精选100题(40)-扑克牌的顺子[算法]

题目:从扑克牌中随机抽5张牌,判断是不是一个顺子,即这5张牌是不是连续的。2-10为数字本身,A为1,J为11,Q为12,K为13,而大小王可以看成任意数字。          分析:这题目很有意思...
  • GarfieldEr007
  • GarfieldEr007
  • 2016-02-23 12:42:12
  • 1479

程序员面试题精选100题(20)-最长公共子串[算法]

题目:如果字符串一的所有字符按其在字符串中的顺序出现在另外一个字符串二中,则字符串一称之为字符串二的子串。注意,并不要求子串(字符串一)的字符必须连续出现在字符串二中。请编写一个函数,输入两个字符串,...
  • GarfieldEr007
  • GarfieldEr007
  • 2016-02-22 21:03:05
  • 664

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

题目在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行、同一列或者同一对角斜线上。下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法。请求出总共有多少种摆法。...
  • SunnyYoona
  • SunnyYoona
  • 2015-04-04 22:14:54
  • 1319

<em>程序员面试题精选100题(</em>经典!)

<em>程序员面试题精选100题</em>-何海涛 立即下载 上传者: SunnyYoona 时间: 2015-02-08 综合评分: 4 积分/C币:10 [<em>程序员面试题精选100题</em>]<em>58</em>.八皇后问题 程序...
  • 2018年04月07日 00:00

程序员面试题精选100题(经典!)

  • 2013年03月19日 15:49
  • 11.41MB
  • 下载
收藏助手
不良信息举报
您举报文章:程序员面试题精选100题:41-50解题报告
举报原因:
原因补充:

(最多只允许输入30个字)