原题网址:http://www.cnblogs.com/xwdreamer/archive/2011/12/13/2296910.htmlhtml
1.把二元查找树转变成排序的双向链表
题目:
输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。
要求不能建立任何新的结点,只调整指针的指向。
10
/ \
6 14
/ \ / \
4 8 12 16
转换成双向链表
4=6=8=10=12=14=16。java
思路汇总:node
(1)每访问到一个parent,递归左子树,递归右子树,链接左子树的最左边,右子树的最右边与根节点的结合处。故递归函数必须标明当前子树左右状况。面试
(2)中序遍历树,记录一个pre,而后每访问到一个节点,就将其加入双向链表中,具体即为与pre的操做。算法
2.设计包含min函数的栈。
定义栈的数据结构,要求添加一个min函数,可以获得栈的最小元素。
要求函数min、push以及pop的时间复杂度都是O(1)。编程
思路汇总:数组
(1)在栈内部定义两个实际的栈结构,一个栈存放主体数据,另外一个栈存放当前最小值,入栈和出栈操做时,同时更新最小值栈。缓存
3.求子数组的最大和
题目:
输入一个整形数组,数组里有正数也有负数。
数组中连续的一个或多个整数组成一个子数组,每一个子数组都有一个和。
求全部子数组的和的最大值。要求时间复杂度为O(n)。数据结构
例如输入的数组为1, -2, 3, 10, -4, 7, 2, -5,和最大的子数组为3, 10, -4, 7, 2,
所以输出为该子数组的和18。函数
思路汇总:
(1)用动态规划思想,定义六个变量:maxStart=0,maxEnd=0,maxSum=a[0],tmpStart=0,tmpEnd=0,tmpSum=a[0]。从头遍历整个数组。
若是tmpSum>maxSum then tmp->max; 若是tmpSum<=0; tmpSum=0;tmpStart = tmpEnd = now-index. 输出maxStart-maxEnd
4.在二元树中找出和为某一值的全部路径
题目:输入一个整数和一棵二元树。
从树的根结点开始往下访问一直到叶结点所通过的全部结点造成一条路径。
打印出和与输入整数相等的全部路径。
例如 输入整数22和以下二元树
10
/ \
5 12
/ \
4 7
则打印出两条路径:10, 12和10, 5, 7。
思路汇总:
(1)用动态规划的思想作,全局建一个缓存的TreeNode的数组,便于输出路径,递归地将sum往下传,过程当中减去通过节点的val,当sum<0,递归终止,当sum==0,且叶节点时
输出缓存数组,并提出数组中当前节点,并返回。当sum>0时,分别递归当前节点的非null左子树和右子树。
5.查找最小的k个元素
题目:输入n个整数,输出其中最小的k个。
例如输入1,2,3,4,5,6,7和8这8个数字,则最小的4个数字为1,2,3和4。
思路汇总:
(1)能够用size为k的堆来作
(2)能够用快排的partion来作。
第6题
腾讯面试题:
给你10分钟时间,根据上排给出十个数,在其下排填出对应的十个数
要求下排每一个数都是先前上排那十个数在下排出现的次数。
上排的十个数以下:
【0,1,2,3,4,5,6,7,8,9】
思路汇总:http://blog.csdn.net/heaven13483/article/details/7925621
第7题
微软亚院之编程判断俩个链表是否相交
给出俩个单向链表的头指针,好比h1,h2,判断这俩个链表是否相交。
为了简化问题,咱们假设俩个链表均不带环。
问题扩展:
1.若是链表可能有环列?
2.若是须要求出俩个链表相交的第一个节点列?
思路汇总:
(1)让h1和h2都遍历到最后一个节点,判断最后节点是否相同。
(2)让其中一个链表h1遍历到最后一个节点,并将最后一个节点链接到h2上,变为判断链表是否有环的问题。
扩展问题1.先判断是否有环,将环点处解开。扩展问题2.与找环点一样的思路。
环问题:fast,slow指针,fast速度2,slow速度1.第一次相遇必定在环上。再分别从h1表头和相遇点等速前进,相交点为入口点。
第8题
此贴选一些 比较怪的题,,因为其中题目自己与算法关系不大,仅考考思惟。特此并做一题。
1.有两个房间,一间房里有三盏灯,另外一间房有控制着三盏灯的三个开关,
这两个房间是 分割开的,从一间里不能看到另外一间的状况。
如今要求受训者分别进这两房间一次,而后判断出这三盏灯分别是由哪一个开关控制的。
有什么办法呢?
2.你让一些人为你工做了七天,你要用一根金条做为报酬。金条被分红七小块,天天给出一块。
若是你只能将金条切割两次,你怎样分给这些工人?
3. ★用一种算法来颠倒一个连接表的顺序。如今在不用递归式的状况下作一遍。
★用一种算法在一个循环的连接表里插入一个节点,但不得穿越连接表。
★用一种算法整理一个数组。你为何选择这种方法?
★用一种算法使通用字符串相匹配。
★颠倒一个字符串。优化速度。优化空间。
★颠倒一个句子中的词的顺序,好比将“我叫克丽丝”转换为“克丽丝叫我”,
实现速度最快,移动最少。
★找到一个子字符串。优化速度。优化空间。
★比较两个字符串,用O(n)时间和恒量空间。
★假设你有一个用1001个整数组成的数组,这些整数是任意排列的,可是你知道全部的整数都在1到1000(包括1000)之间。此外,除一个数字出现两次外,其余全部数字只出现一次。假设你只能对这个数组作一次处理,用一种算法找出重复的那个数字。若是你在运算中使用了辅助的存储方式,那么你能找到不用这种方式的算法吗?
★不用乘法或加法增长8倍。如今用一样的方法增长7倍。
思路汇总:(待分析)
第9题
判断整数序列是否是二元查找树的后序遍历结果
题目:输入一个整数数组,判断该数组是否是某二元查找树的后序遍历的结果。
若是是返回true,不然返回false。
例如输入五、七、六、九、十一、十、8,因为这一整数序列是以下树的后序遍历结果:
8
/ \
6 10
/ \ / \
5 7 9 11
所以返回true。
若是输入七、四、六、5,没有哪棵树的后序遍历的结果是这个序列,所以返回false。
思路汇总:
(1)递归地检查BSTreeCheck(int[] a, int start, int end),a[end]是根节点。知足,数组能被分为两部分,左部分不大于根,右部分不小于根。
第10题
翻转句子中单词的顺序。
题目:输入一个英文句子,翻转句子中单词的顺序,但单词内字符的顺序不变。
句子中单词以空格符隔开。为简单起见,标点符号和普通字母同样处理。
例如输入“I am a student.”,则输出“student. a am I”。
思路汇总:
(1)用split(),返回数组。而后倒序输出
第11题
求二叉树中节点的最大距离...
若是咱们把二叉树当作一个图,父子节点之间的连线当作是双向的,
咱们姑且定义"距离"为两节点之间边的个数。
写一个程序,
求一棵二叉树中相距最远的两个节点之间的距离。
思路汇总:
(1)写一个递归函数,全局存一个最大距离,初始化为-1,递归函数返回一个数组,当前节点最大深度,当前节点最大距离,递归函数内部将当前节点左子树最大深度+右子树最大深度与左右子树最大距离比较,再与全局最大距离比较。
最终全局存放的最大距离为最大距离。(当前节点往上一个节点返回时,别忘了算上本身对深度的贡献)
第12题
题目:求1+2+…+n,
要求不能使用乘除法、for、while、if、else、switch、case等关键字以及条件判断语句(A?B:C)。
思路汇总:http://www.cnblogs.com/lzmfywz/archive/2013/04/22/3036370.html
java中能够利用&&短路 boolean tmp = (n > 0) && (addFun(n-1)!=0);
第13题:
题目:输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。
链表结点定义以下:
struct ListNode
{
int m_nKey;
ListNode* m_pNext;
};
思路汇总:先定义一个first指针走k步,若是k步以前到null返回null。而后定义一个second指针从头开始,与first同时继续前进,直到first所指的节点为tail节点(或next为null)。
第14题:
题目:输入一个已经按升序排序过的数组和一个数字,
在数组中查找两个数,使得它们的和正好是输入的那个数字。
要求时间复杂度是O(n)。若是有多对数字的和等于输入的数字,输出任意一对便可。
例如输入数组一、二、四、七、十一、15和数字15。因为4+11=15,所以输出4和11。
思路汇总:
设置两个index: start = 0,end = a.length-1; 而后while(start<end){若是sum>15,end- - ,若是sum<15,end+ +,else 输出a[start] 和a[end] 而且break}。
第15题:
题目:输入一颗二元查找树,将该树转换为它的镜像,
即在转换后的二元查找树中,左子树的结点都大于右子树的结点。
用递归和循环两种方法完成树的镜像转换。
例如输入:
8
/ \
6 10
/\ /\
5 7 9 11
输出:
8
/ \
10 6
/\ /\
11 9 7 5
定义二元查找树的结点为:
struct BSTreeNode // a node in the binary search tree (BST)
{
int m_nValue; // value of node
BSTreeNode *m_pLeft; // left child of node
BSTreeNode *m_pRight; // right child of node
};
思路汇总:
(1)递归方法:从根节点递归,互换left和right
(2)循环方法: 须要一个辅助栈,将根节点压栈。循环条件为栈非空,取出栈顶节点,左右互换,将子节点入栈。
第16题:
题目(微软):
输入一颗二元树,从上往下按层打印树的每一个结点,同一层中按照从左往右的顺序打印。
例如输入
8
/ \
6 10
/ \ / \
5 7 9 11
输出8 6 10 5 7 9 11。
思路汇总:
(1)辅助队列来作
第17题:
题目:在一个字符串中找到第一个只出现一次的字符。如输入abaccdeff,则输出b。
分析:这道题是2006年google的一道笔试题。
思路汇总:
(1)256大小的int数组,遍历字符串,更新数组内容,再次遍历字符串,找到第一个个数不为一的字符。O(n)的时间复杂度。
第18题:
题目:n个数字(0,1,…,n-1)造成一个圆圈,从数字0开始,
每次从这个圆圈中删除第m个数字(第一个为当前数字自己,第二个为当前数字的下一个数字)。
当一个数字删除后,从被删除数字的下一个继续删除第m个数字。
求出在这个圆圈中剩下的最后一个数字。
July:我想,这个题目,很多人已经 见识过了。
思路汇总:
(1)http://www.360doc.com/content/12/0314/13/1429048_194255548.shtml
(2)链表作
第19题:
题目:定义Fibonacci数列以下:
/ 0 n=0
f(n)= 1 n=1
\ f(n-1)+f(n-2) n=2
输入n,用最快的方法求该数列的第n项。
分析:在不少C语言教科书中讲到递归函数的时候,都会用Fibonacci做为例子。
思路汇总:
(1)递归的方法,最屌丝了。
(2)迭代的方法,维护一个f(n-1)和f(n-2)的缓存。
第21题
2010年中兴面试题
编程求解:
输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,
使其和等于 m ,要求将其中全部的可能组合列出来.
思路汇总:
用动态规划的思想,维护一个缓存数组,和一个index(其实就是能够维护一个栈),从n到1遍历,依次入栈,知足条件后或者没法继续递归下去后,pop栈顶元素。这样就能获得各类组合。
组合的条件能够不少种,好比能够设定组合条件为固定数目的整数的组合,这样,能够判断栈大小。本题的组合条件就是和为m,那么每当有整数入栈时,从m中剔除这个值,并将调整后的m递归传递
给下一个函数,直到m=0时,输出栈中全部元素,并pop栈顶元素。m<0,直接pop。(注意:本题由于是动态规划的思想,有重叠最小子问题,因此用的是栈思想,可是实际是用一个缓存数组和index)
第22题:
有4张红色的牌和4张蓝色的牌,主持人先拿任意两张,再分别在A、B、C三人额头上贴任意两张牌,
A、B、C三人均可以看见其他两人额头上的牌,看完后让他们猜本身额头上是什么颜色的牌,
A说不知道,B说不知道,C说不知道,而后A说知道了。
请教如何推理,A是怎么知道的。
若是用程序,又怎么实现呢?
思路汇总:
牌的组合有:rb,rr,bb这三种,进行全罗列。(程序实现的思路有待思考)
第23题:
用最简单,最快速的方法计算出下面这个圆形是否和正方形相交。"
3D坐标系 原点(0.0,0.0,0.0)
圆形:
半径r = 3.0
圆心o = (*.*, 0.0, *.*)
正方形:
4个角坐标;
1:(*.*, 0.0, *.*)
2:(*.*, 0.0, *.*)
3:(*.*, 0.0, *.*)
4:(*.*, 0.0, *.*)
思路汇总:
算出四个点离圆形最近的两个点,算圆心到两点组成直线的距离是否小于r。
http://blog.csdn.net/bitzhuxb/article/details/8641636
第24题:
链表操做,
(1).单链表就地逆置,
(2)合并链表
思路汇总:
(1)题:用三个指针,pre,cur,next
(2)题:p1,p2,cur
第25题:
写一个函数,它的原形是int continumax(char *outputstr,char *intputstr)
功能:
在字符串中找出连续最长的数字串,并把这个串的长度返回,
并把这个最长数字串付给其中一个函数参数outputstr所指内存。
例如:"abcd12345ed125ss123456789"的首地址传给intputstr后,函数将返回9,
outputstr所指的值为123456789
思路汇总:
相似于第三题,维护(maxStart,maxEnd,maxLen),遍历字符串,跟新(tmpStart,tmpEnd,tmpLen),若是tmpLen>maxLen,更新max三个值。
26.左旋转字符串
题目:
定义字符串的左旋转操做:把字符串前面的若干个字符移动到字符串的尾部。
如把字符串abcdef左旋转2位获得字符串cdefab。请实现字符串左旋转的函数。
要求时间对长度为n的字符串操做的复杂度为O(n),辅助内存为O(1)。
思路汇总:
1.写一个针对字符串逆置的函数,reverse(),这样若是将须要左旋的字符串为AB,左旋的部分为A,那么能够reverse(A);reverse(B);reverse(AB);
其中,reverse()函数的的时间复杂度为O(n),空间复杂度为O(1)。
27.跳台阶问题
题目:一个台阶总共有n级,若是一次能够跳1级,也能够跳2级。
求总共有多少种跳法,并分析算法的时间复杂度。
这道题最近常常出现,包括MicroStrategy等比较重视算法的公司
都曾前后选用过个这道题做为面试题或者笔试题。
思路分析:
f(n) = f(n-1)+f(n-2);
28.整数的二进制表示中1的个数
题目:输入一个整数,求该整数的二进制表达中有多少个1。
例如输入10,因为其二进制表示为1010,有两个1,所以输出2。
分析:
这是一道很基本的考查位运算的面试题。
包括微软在内的不少公司都曾采用过这道题。
思路汇总:
设定一个mask = 1, 而后不断mask<<1,直至mask为0,其间,用每一次得到的mask & 给定的数,得到相应位置上的值为1仍是0,统计count
29.栈的push、pop序列
题目:输入两个整数序列。其中一个序列表示栈的push顺序,
判断另外一个序列有没有多是对应的pop顺序。
为了简单起见,咱们假设push序列的任意两个整数都是不相等的。
思路汇总:
创建一个栈,将push序列的数不断push到栈中,这能够算作一个shift操做,而后每一步都比较栈顶元素与pop序列的第一个元素,若是相同,就pop栈,而且删除pop序列第一个元素,这能够定义为reduce操做。
当push序列为空,栈为空,且pop序列为空时,返回true,不然返回false
30.在从1到n的正数中1出现的次数
题目:输入一个整数n,求从1到n这n个整数的十进制表示中1出现的次数。
例如输入12,从1到12这些整数中包含1 的数字有1,10,11和12,1一共出现了5次。
分析:这是一道广为流传的google面试题。
思路汇总:分别对最高位,中间位,最低位进行分析,分别分析他们是0,1,或者大于1的状况 http://blog.sina.com.cn/s/blog_3fc85e260100mbss.html
31.华为面试题:
一相似于蜂窝的结构的图,进行搜索最短路径(要求5分钟)(没看懂题目)
32.
有两个序列a,b,大小都为n,序列元素的值任意整数,无序;
要求:经过交换a,b中的元素,使[序列a元素的和]与[序列b元素的和]之间的差最小。
例如:
var a=[100,99,98,1,2, 3];
var b=[1, 2, 3, 4,5,40];
思路分析:
穷举法: (复杂度很大,并且存在被交换到另外一边的元素又再次被交换回来的风险)
首先先计算a,b中元素和之间的差绝对值abs,而后逐一的把a中的元素和b中的任一元素做比较,若是它们交换后的差值绝对值abs小于原来的值abs,那么就把a,b交换,并从新计算a和b的绝对值,
这种动做反复的进行,直到a中任一的元素都不能和b中的任一元素交换为止。
贪婪搜索:(O(n3),能够证实不存在穷举法中存在的问题)
当前数组a和数组b的和之差为A = sum(a) - sum(b),a的第i个元素和b的第j个元素交换后,a和b的和之差为
A' = sum(a) - a[i] + b[j] - (sum(b) - b[j] + a[i])
= sum(a) - sum(b) - 2 (a[i] - b[j])
= A - 2 (a[i] - b[j])
设x = a[i] - b[j],那么
A' = |A - 2x|,固然A' 越小也好,因此当x 在 (0,A)之间时,作这样的交换才能使得交换后的a和b的和之差变小,x越接近A/2效果越好,若是找不到在(0,A)之间的x,则当前的a和b就是答案。
因此算法大概以下:在a和b中寻找使得x在(0,A)之间而且最接近A/2的i和j,交换相应的i和j元素,从新计算A后,重复前面的步骤直至找不到(0,A)之间的x为止。
回溯法:(复杂度还不知道)
http://blog.csdn.net/ljsspace/article/details/6434621
33.
实现一个挺高级的字符匹配算法:
给一串很长字符串,要求找到符合要求的字符串,例如目的串:123
1******3***2 ,12*****3这些都要找出来
思路分析:
因为此处都是ASSIC字符,因此能够建一个256大小的bool数组,index是ASSIC字符码,而后遍历待匹配字符串统计,再遍历bool数组看是否匹配模式字符串
34.
实现一个队列。
队列的应用场景为:
一个生产者线程将int类型的数入列,一个消费者线程将int类型的数出列
思路分析:
java中可使用synchronized关键字,wait(),和notifyAll()方法。其中队列是否为空做为消费者的判断条件,队列是否为满做为生产者的判断条件