程序员面试算法概率那些事

来源:互联网 发布:淘宝网店授权书 编辑:程序博客网 时间:2024/06/07 16:20

PS:刷一遍经典的算法题, 让自己随时保持头脑"清醒"

算法题

1. 题目:输入一个单向链表,输出该链表中倒数第k个结点。链表的倒数第0个结点为链表的尾指针。

类似的试题:输入一个单向链表。如果该链表的结点数为奇数,输出中间的结点;如果链表结点数为偶数,输出中间两个结点前面的一个。

2. 输入一个整数数组,实现一个函数来调整该数组中数字的顺序,使得所有的奇数位于数组的前半部分,所有的偶数位于位于数组的后半部分,并保证奇数和奇数,偶数和偶数之间的相对位置不变

类似的简化题:  不要求 相对位置不变

3. 链表反转 。 时间复杂度O(n)

4.  二分查找算法

变形1: 给一个有N个互不相同的元素的已排序数组,返回小于或等于给定key的最大元素。 例如输入为 A = {-1, 2, 3, 5, 6, 8, 9, 10}   key = 7,应该返回6

变形2:给一个有重复元素的已排序数组,找出给定的元素key出现的次数,时间复杂度要求为logN.

变形3:给一个有重复元素的已排序数组 思路就是分别找出key 第一次出现的位置和最后一次出现的位置

变形4:有一个已排序的数组(无相同元素)在未知的位置进行了旋转操作,找出在新数组中的最小元素所在的位置。

例如:原数组 {1,2,3,4,5,6,7,8,9,10}, 旋转后的数组可能是 {6,7,8,9,10, 1,2,3,4,5 },也可能是 {8,9,10,1,2,3,4,5,6,7 }

概率题

1. 一根木棒,截成三截,组成三角形的概率是多少?
设第一段截x,第二段截y,第三段1-x-y。
考虑所有可能的截法。可能的截法中必须保证三条边都是正数且小于原来边长,则有0<x<1,0<y<1,0<1-x-y<1,画图可知,(x,y)必须在单位正方形的左下角的半个直角三角形里,面积为1/2。
然后考虑能形成三角形的截法。首先要满足刚才的三个条件0<x<1,0<y<1,0<1-x-y<1,然后必须符合三角形的边的要求,即两边之和大于第三边,x+y>1-x-y,x+1-x-y>y,y+1-x-y>x,化简即得
0<x<1/2,0<y<1/2,1/2<x+y<1
画图可知,此时(x,y)必须在边长为1/2的三角形的右上角的半个直角三角形里,面积为1/8。
于是最终概率为 (1/8)/(1/2) = 1/4。

2.  已知一随机发生器,产生0的概率是p,产生1的概率是1-p,现在要你构造一个发生器,使得它产生0和1的概率均为1/2。
考虑连续产生两个随机数,结果只有四种可能:00、01、10、11,其中产生01和产生10的概率是相等的,均为p*(1-p),于是可以利用这个概率相等的特性等概率地产生01随机数。
比如把01映射为0,10映射为1。于是整个方案就是:
产生两个随机数,如果结果是00或11就丢弃重来,如果结果是01则产生0,结果是10则产生1。

类似的:

已知一随机发生器,产生的数字的分布不清楚,现在要你构造一个发生器,使得它产生0和1的概率均为1/2。
思路类似,考虑连续产生两个随机数a、b,结果有三种情况a==b,a>b,a<b,其中由于a和b的对称性,a>b和a<b出现的概率是相等的,于是可以利用这个概率相等的特性等概率地产生01随机数。

类似的:

已知一随机发生器,产生0的概率是p,产生1的概率是1-p,构造一个发生器,使得它构造1、2、3的概率均为1/3;…。更一般地,构造一个发生器,使得它构造1、2、3、…n的概率均为1/n。
此时我们已经知道,要从n个数中等概率地产生一个随机数,关键是要找到n个或更多个出现概率相等的事件,然后我们重复随机地产生事件,如果是跟这n个事件不同的事件直接忽略,直到产生这n个事件中的一个,然后就产生跟这个事件匹配的随机数。由于n个事件发生的概率相等,于是产生的随机数的概率也是相等的。
考虑连续产生x个随机数,结果应该是x个0跟1的组合,为了使某些结果出现的概率相等,我们应该要让这个结果中0和1出现的次数相等,即各占一半。于是x的长度必须是偶数的,为了方便,考虑连续产生2x个随机数。每个0跟1各出现一半的结果可以赋予1到n的某个数,为了能够表示这n个数,需要0跟1各出现一半的总结果数大于等于n,即
C(2*x, x) >= n
解出最小的x即为效率最高的x。
然后把前n个0和1个出现一半的结果分别赋予1到n的值。随机时连续产生2*x个数,如果不是这n个结果中的一个则重新随机,如果是的话则产生对应的值作为随机结果。

3. 已知有个rand7()的函数,返回1到7随机自然数,怎样利用这个rand7()构造rand10(),随机1~10。
产生随机数的主要原则是每个数出现的概率是相等的,如果可以得到一组等概率出现的数字,那么就可以从中找到映射为1~10的方法。
rand7()返回1~7的自然数,构造新的函数 (rand7()-1)*7 + rand7(),这个函数会随机产生1~49的自然数。原因是1~49中的每个数只有唯一的第一个rand7()的值和第二个rand7()的值表示,于是它们出现的概率是相等。
但是这里的数字太多,可以丢弃41~49的数字,把1~40的数字分成10组,每组映射成1~10中的一个,于是可以得到随机的结果。
具体方法是,利用(rand7()-1)*7 + rand7()产生随机数x,如果大于40则继续随机直到小于等于40为止,如果小于等于40,则产生的随机数为(x-1)/4+1。

类似的:

已知有个randM()的函数,返回1到M随机自然数,怎样利用这个randM()构造randN(),随机1~N。
上题的扩展。
当N<=M时可以直接得到。
当N>M时,类似构造(randM()-1)*M + randM(),可以产生1~M^2(即randM^2),可以在M^2中选出N个构造1~N的映射。
如果M^2还是没有N大,则可以对于randM^2继续构造,直到成功为止。

4. 

一个三角形, 三个端点上有三只蚂蚁,蚂蚁可以绕任意边走,问蚂蚁不相撞的概率是多少?
1.每个蚂蚁在方向的选择上有且只有2种可能,共有3只蚂蚁,所以共有2的3次方种可能
2.不相撞有有2种可能,即全为顺时针方向或全为逆时针方向。
不相撞概率=不相撞/全部=2/8

5.

甲乙两个人答对一道题的概率分别为90%和80%,对于一道判断题,他们都选择了“正确”,问这道题正确的概率

类似的 条件概率

6.  找等概率事件

1) 题目:已知一随机发生器A,产生0的概率是p,产生1的概率是1-p,现在要你构造一个发生器B, 使得它构造0和1的概率均为1/2。

原始的随机数生成器,生成0 的概率为p,生成1的概率为1-p,那么怎么构造才能使得生成0和1的概率相等呢。或者说有两个独立的事件的概率是相等呢?
这样来做一下,让该随机数生成器生成两个数,那么序列是00,01,10,11概率分别为 p*p,p(1-p),(1-p)p,(1-p)*(1-p)
很明显,这四种情况中存在两个独立的事件概率是相等。也就是01和10,那么我把01看成是0,10看成是1,那么他们输出的概率均为p(1-p),其他的情况舍弃。这样就得到了0和1均等生成的随机器了。

2) 如果有该随机发生器A,产生0的概率是p,产生1的概率是1-p,输入一个指定的N,如何以以1/N的概率随机产生1-N?

3)已知有个rand7()的函数,返回1到7随机自然数,让利用这个rand7()构造rand10() 随机1~10

4)如果能够得到一组等概率的数,不管是什么数,只要等概率而且个数大于10,那么问题就可以解决了。
发现 (rand7() - 1) * 7 + rand7(),可以等概率的生成1到49。
呵呵,这不就得了,只要把11-49砍掉就可以了。不过这样的效率比较低。可以砍掉41-49,然后在把1-40映射到1-10,那么问题也就解决了。

5)给定能随机生成整数1到5的函数,写出能随机生成整数1到7的函数

6)

7. 

有一苹果,两个人抛硬币来决定谁吃这个苹果,先抛到正面者吃。问先抛者吃到苹果的概率是多少?

1/2 + 1/8 + 1/32+ ……  最后的结果就是 P = 2/3
8.

有一对夫妇,先后生了两个孩子,其中一个孩子是女孩,问另一个孩子是男孩的概率是多大?

男女,男男,女男,女女

9.  求π

方法1. 非 概率算法,用级数来做的:π = 4 * (1 - 1/3 + 1/5 - 1/7 + ... )

方法2: 画一个正方形,在正方形的内部内切一个圆形,随机地往这个区域扔东西(比如小沙子),最后用:
圆的面积/正方形的面积 = 圆里面的沙粒数量/正方形里的沙粒数量(当然包括圆里面的)
这种方式也可以求得π的比较精确的结果。

设 正方形边长=2r, s(正方形)=4r*r; 圆面积= πr*r






原创粉丝点击