出题:Josephus Cycle,约瑟夫环问题.k个数字连成一个环,第一个数字为1.首先从1开始计数删除第m个数字:然后从上次被删除的数字的下一个数字开始计数,删除第m个数字:重复进行第二步直到只剩下一个数字:输出最后剩下的一个数字: 分析: 解法1:考虑到问题的特殊性,可以使用哑元素表示删除的元素从而避免由于删除元素带来的额外操作,所以链表实现的话不用考虑删除操作,数组实现的话不用考虑内存移动操作.当然完全可以不适用哑元素,对于链表而言可以节省查找时间,数组的话需要增加数组元素的平移开销:…
用nodeJs写算法题 咱们前端使用算法的地方不多,但是为了校招笔试,不得不针对算法题去练习呀! 好不容易下定决心 攻克算法题.发现js并不能像c语言一样自建输入输出流.只能回去学习c语言了吗?其实不用,node也能很好帮助我们完成!且笔试都支持用nodeJs,实际上就是用JS编程,只是用到了node的一些输入输出流方法. 我们看看最简单的使用模板:(转载) var readline = require('readline'); rl = readline.createInterface({ i…
在上一篇文章 小小c#算法题 - 10 - 求树的深度中,用到了树的数据结构,树型结构是一类重要的非线性数据结构,树是以分支关系定义的层次结构,是n(n>=0)个结点的有限集.但在那篇文章中,只是简单地把结点组合到了一块. 这次,我们来简单定义一棵二叉树的数据结构,并实现其先序(根)遍历.中序(根)遍历.后序(根)遍历算法. 下面先来看一下先序遍历,中序遍历,后序遍历的定义: 先序遍历: 若二叉树为空,则空操作,否则 (1)访问根结点: (2)先序遍历左子树: (3)先序遍历右子树: 中序遍历:…
题目:输入两个整数序列.其中一个序列表示栈的push 顺序,判断另一个序列有没有可能是对应的pop 顺序.为了简单起见,我们假设push 序列的任意两个整数都是不相等的. 例如:输入的push 序列是1.2.3.4.5,那么4.5.3.2.1 就有可能是一个pop 系列 1.思路 (1)假设栈顶元素等于输出指针指向元素,弹出栈顶元素并后移输出指针: (2)倘若不满足(1),则压栈输入指针元素,直到输入指针元素等于输出指针元素或者输出指针已经指向空.是前者情况,则分别省略压栈出栈操作,直接后移输入…
出题:给定一个数字序列,其中每个数字最多出现两次,只有一个数字仅出现了一次,如何快速找出其中仅出现了一次的数字: 分析: 由于知道一个数字异或操作它本身(X^X=0)都为0,而任何数字异或操作0都为它本身,所以当所有的数字序列都异或操作之后,所有出现两次的数字异或操作之后的结果都为0,则最后剩下的结果就是那个仅出现了一次的数字: 如果有多个数字都仅仅出现了一次,则上述的异或操作方法不再适用:如果确定只有两个数字只出现了一次,则可以利用X+Y=a和XY=b求解: 解题: int findSingl…
出题:判断一个单向链表是否有环,如果有环则找到环入口节点: 分析: 第一个问题:使用快慢指针(fast指针一次走两步,slow指针一次走一步,并判断是否到达NULL,如果fast==slow成立,则说明链表有环): 第二个问题:fast与slow相遇时,slow一定还没有走完一圈(反证法可证明):   示意图 A为起始点,B为环入口点,C为相遇点,则a1=|AB|表示起始点到换入口的距离,a2=|CB|表示相遇点到环入口点的距离,s1=|AB|+|BC|表示slow指针走的长度,s2表示fast…
出题:输入一个整数N,求从1到N这N个整数的十进制表示中‘1’出现的次数: 分析: 从左向右处理string表示的数字:当前数字长度为n,判断最左边一位数字字符: 如果是0,则直接递归下一位: 如果是1,则计数有两个来源,一个是n位数数字(实际就是除去最高位之后的数字大小,加上1,当其余位全部为0的时候),另一个是n-1,n-2,……,1位数字,使用SpecialPower可以计算: 如果是其他数字,则计数有两个来源,一个是n,n-1,n-2,……,1位数字,使用SpecialPower可以计算…
出题:输入一个整数,要求计算此整数的二进制表示中1的个数 分析: 如果整数表示为k,当其是负数的时候,使用1<<i分别检测k的每一位:当其位整数的时候,则k/2表示将其二进制表示右移一位,k%2 ==0表示其是否是偶数,如果不是则说明当前二进制表示的最右边一位为1,当k==0成立的时候移位结束: 另外还可以使用‘消1’的方法,如果二进制表示A为'****1000',则A-1为'****0111',也就是我们仅关注二进制表示最右边的第一个 1,这样的话A&(A-1)的结果就可以将最右边的…
出题:输入N个整数,要求输出其中最小的K个数: 分析: 快速排序和最小堆都可以解决最小(大)K个数的问题(时间复杂度为O(NlogN)):另外可以建立大小为K的最大堆,将前K个数不断插入最大堆,对于之后的N-K个数,依次与堆顶元素进行比较,如果新元素更小则删除当前堆顶元素,并更新最大堆:如果新元素大则跳过: 第一种实现:快速排序框架,插入排序处理小子文件,随机函数选取split点,双向扫描: 第二种实现:最小堆框架,基于fixUp的堆构建策略(数组整体更新,bottom up),通过删除前K个堆…
出题:在已经排序的数组中,找出给定数字出现的次数: 分析: 解法1:由于数组已经排序,所以可以考虑使用二分查找确定给定数字A的第一个出现的位置m和最后一个出现的位置n,最后m-n+1就是A出现的次数:使用二分查找可疑快速确定给定数字,但是如果确定其左右范围则比较麻烦,对编码细节要求较高: 解法2:HashTable解决 解题: int occurrence(int *array, int length, int t) { /** * 寻找t所在的区间 * 此阶段之后left和right索引 *…