Cracking the coding interview--Q10.1~Q10.7

来源:互联网 发布:unity3d 导入max文件 编辑:程序博客网 时间:2024/06/11 18:37

题目10.1

译文:

你有一个篮球架,可以在以下游戏中选择一个来玩。

游戏1:投一次球,进了算赢。

游戏2:投三次球,至少要进2个才算赢。

如果命中率是p,那么p是什么值时你会选游戏1来玩?或p是什么值时你会选择游戏2?

解答10.1

由题意,游戏1的命中率为p;游戏2命中率为:C(2,3)*p^2*(1-p)+p^3=3*p^2-2*p^3,所以由

          p>3*p^2-2*p^3

得p<0.5, 即当p小于0.5时,选游戏1玩,p>0.5时,选游戏2玩


题目10.2

译文:

3只蚂蚁在三角形的3个顶点上,现在让它们沿着三角形的边开始运动, 发生碰撞的概率是多少?如果是n只蚂蚁在n边形的n个顶点上呢,碰撞的概率又是多少?

解答10.2

首先,题目中没有提到蚂蚁运动的速度,所以认为它们的速度一样,不会发生一只蚂蚁追上另一只蚂蚁的情况(面试时可以向面试官确认一下)。 对于任何1只蚂蚁,它有2条边可以选择来走。不会发生冲突的情况是, 所有的蚂蚁都顺时针走或是逆时针走,剩下的情况都是会冲突的。所以,冲突的概率为:

                            p=1-2*(1/2)^3=3/4

同理,n只蚂蚁在n边形的n个顶点,有

                            p=1-2*(1/2)^n


题目10.3

译文:

给定笛卡尔坐标系中的两条直线,判断两条线是否相交。

解答10.3

我们用斜截式来表示直线`y=ax+b`,两个直线是否相交,就很容易判断。一般情况,两条直线的斜率不相同,两直线就相交了。同时考虑一些边界条件
当直线垂直于x轴的时候,直线斜率不存在。还有当两条直线重合时,也认为两条直线是相交的。再者,需要考虑的问题就是计算中斜率是用浮点数的表示
当两个浮点数之间的误差,小于规定的阈值的时候,我们要认为二者是相等的


题目10.4

译文:

写一个函数实现*, - , /操作,你能使用的操作只有加法+。

解答10.4

首先对于这道题目,我们要和面试官确认一下,是不是只针对整数来讨论。 你自己在心里看到这道题目,也要大概估计到应该只在整数范围内考察。否则, 要你只用加法实现个浮点数相乘或是相除,恐怕就不太好办了。

对于乘法,比如a*b(a>0, b>0),可以视为a个b相加,或是b个a相加。 如果a,b中有负数呢?我们可以先将它们取绝对值相乘,然后再根据同号相乘为正, 异号相乘为负给结果加上符号。其中,我们还可以做一点小优化, 即如果a<b,就求a个b相加;如果a>b,就求b个a相加。这样可以加法运算次数。

对于减法,a-b,我们只需要转变为a+(-b)即可。

对于除法,a/b,首先我们要考虑的是b不能为0.当b等于0时,抛出异常或返回无穷大(程序 中定义的一个值)。与乘法相同,我们都先对a和b取绝对值,然后不断地从a中减去b, 相应的商数加1。直到a已经不够给b减了,再根据a和b的符号决定是否给商数加上负号即可。

代码如下:

class Q10_4{public static int INF=~(1<<31);public static void main(String[] args){int[] a={8,0,-8,-5,9};int[] b={3,5,3,0,-3};for(int i=0;i<5;i++){System.out.print(sub(a[i],b[i])+" ");System.out.print(times(a[i],b[i])+" ");System.out.println(divide(a[i],b[i]));}}public static void swap(int a,int b){a=a^b;b=a^b;a=a^b;}public static int flipsign(int a){int d=a<0?1:-1;int opa=0;while(a!=0){a+=d;opa+=d;}return opa;}public static int abs(int a){if(a<0) a=flipsign(a);return a;}public static boolean opsign(int a,int b){return (a<0&&b>0)||(a>0&&b<0);}public static int sub(int a,int b){return a+flipsign(b);}public static int times(int a,int b){int aa=abs(a);int bb=abs(b);int res=0;if(aa<bb) swap(aa,bb);for(int i=0;i<bb;++i,res+=aa);if(opsign(a,b)) res=flipsign(res);return res;}public static int divide(int a,int b){if(b==0) return INF;int aa=abs(a); int bb=abs(b);int res=0;for(;(aa-=bb)>=0;++res);if(opsign(a,b))res=flipsign(res);return res;}}


题目10.5

译文:

给出二维平面上的两个正方形,找到一条直线能同时将两个正方形都分为面积相等的两半。

解答10.5

由一条过正方形(矩形)中心的直线,可以将正方形(矩形)的面积分成两半。所以,只要该直线经过两个正方形的中心即可。


题目10.6

译文:

在一个二维图上有许多点,找出一条经过最多点的直线。

解答10.6

设共有n个点。将n个顶点之间两两连线,则共计2^n-2条连线。将每条线作为key值,连接的两点作为value。当遍历完所有连线后,具有相同的斜率和截距的连线所
组成的点就拥有相同的key值,然后,数一下一共有多少个不重复的点就可以了。这里仍然需要注意的就是斜率和截距的浮点数表示,将直线作为key值,我们需要重新
计算hashcode,才能够保证key值的正确。


题目10.7

译文:

设计算法,找到质因数只有3,5或7的第k个数。

解答10.7

首先,我们可以将满足条件的前几个数列出来,以此寻找解题思路。

一种简单的思路就是对于已经列出的数,我们依次去乘以3,5,7得到一组数 然后找出最小且还没有列出的数,加入到这个列表。然后重复上面的步骤: 乘以3,5,7,找出最小且还没有列出的数……这个方法的时间复杂度是O(n2 )。

这种思路存在一个问题,就是重复计算。比如对于上面那个表,我想计算下一个数, 那么我用3,5,7去乘以表中的每一个数,然后找出最小且没有用过的数。 可是像3*3,3*5,3*7,5*5,5*7等等都是已经计算过且已经用了的, 按照上面的算法就会不断地重复计算。那我们有没什么办法可以避免重复计算呢? 那就是将已经计算出来的数保存好,并且保持它们有序。为了避免出现先用3乘以5, 然后又用5去乘以3的这种情况出现(这样会使我们维护的数中出现重复), 我们可以用3个队列来维护这些数。第1个队列负责乘以3,第2个队列负责乘以5, 第3个队列负责乘以7。算法描述和代码如下:

/*1. 初始化结果res=1和队列q3,q5,q72. 分别往q3,q5,q7插入1*3,1*5,1*73. 求出三个队列的队头元素中最小的那个x,更新结果res=x4. 如果x在:    q3中,那么从q3中移除x,并向q3,q5,q7插入3*x,5*x,7*x    q5中,那么从q5中移除x,并向q5,q7插入5*x,7*x    q7中,那么从q7中移除x,并向q7插入7*x5. 重复步骤3-5,直到找到第k个满足条件的数注意,当x出现在q5中,我们没往q3中插入3*x,那是因为这个数在q5中已经插入过了。*/import java.util.LinkedList;class Q10_7{public static void main(String[] args){for(int i=1;i<20;++i){System.out.println(get_num(i)+" ");}}public static int mini(int a, int b){    return a < b ? a : b;}public static int mini(int a, int b, int c){    return mini(mini(a, b), c);}public static int get_num(int k){if(k<=0) return 0;int val=1;LinkedList<Integer> q3=new LinkedList<Integer>();LinkedList<Integer> q5=new LinkedList<Integer>();LinkedList<Integer> q7=new LinkedList<Integer>();q3.add(3);q5.add(5);q7.add(7);for(--k;k>0;--k){val=mini(q3.peek(),mini(q5.peek(),q7.peek()));if(val==q7.peek()){q7.remove();}else{if(val==q5.peek()){q5.remove();}else{if(val==q3.peek()){q3.remove();q3.add(3*val);}}q5.add(5*val);}q7.add(7*val);}return val;}}
注:参考:http://hawstein.com/posts/ctci-ch10-math.html

---EOF---


0 0
原创粉丝点击