面试大厂的时候尤其喜欢考验算法和智力题,例如腾讯的wxg和字节跳动等。
笔者在参加字节跳动的两次面试过程中都无一例外经历了智力题的考察,所以对这部分内容有一定的预先准备还是很有必要的。
且有的智力题可能不光要伪代码解释,或者说思路,还需要配合实际代码来跑结果,所以提前了解很需要。
有 20 瓶药丸,其中 19 瓶药丸质量相同为 1 克,剩下⼀瓶药丸质量为 1.1 克。瓶⼦中有⽆数个药丸。要求⽤⼀次天平找出药丸质量 1.1 克的药瓶。
如何用rand3()或rand5()表示rand7()?
对于rand3()
rand3() 实现 rand7() 的方法是利用 rand3() 来生成一个范围在 [0, 7) 之间的随机数。
具体实现方法如下:
调用 rand3() 三次,得到三个随机数 rand1、rand2、rand3。
将这三个随机数分别对 3 取模,得到三个数:rand1 % 3、rand2 % 3、rand3 % 3。
计算 (rand1 % 3) * 3 + (rand2 % 3),得到一个数。
如果该数小于 6,则该数即为所求的随机数,否则再次调用 rand3()。
这样可以保证生成的随机数在 [0, 7) 范围内,并且每个数的概率都相同。
取到0的概率,假设第一次就取到 概率是1/9,但也有可能第一次没取到,第二次才取到,那么第二次取到的概率是2/9 * 1/9, 也有可能是第三次取到,第三次取到的概率是(2/9)的平方 * 1/9,这样所以的加起来是1/9 * (9 / 7) * (1- (2/9)的n+1次方),n趋于无穷的情况下概率就是1/7
对于rand5()
先看New Bing的回答:
This is a classic interview question that tests your understanding of probability and randomness. One way to implement rand7() using rand5() is to use rejection sampling. Here’s how it works:
Generate a random number between 1 and 5 using rand5(). Let’s call this number x.
Generate another random number between 1 and 5 using rand5(). Let’s call this number y.
Compute z = (x - 1) * 5 + (y - 1) + 1.
If z is greater than 21, reject it and go back to step 1.
Otherwise, return z % 7 + 1.
The idea behind this algorithm is that we generate a random number between 1 and 25 (inclusive) using two calls to rand5(). We then reject any number greater than 21, since there are only 21 numbers between 1 and 25 that are divisible by 7 (i.e., 7, 14, and 21). This gives us a uniform distribution over the numbers between 1 and 21 that are divisible by 7, which we can then map to the numbers between 1 and 7.
Note that this algorithm has an expected running time of O(1), since we only need to make two calls to rand5() on average before we generate a valid number.
Rand5() + Rand5() - 1
上述代码可以生成1到9的数,但它们是等概率生成的吗?不是。生成1只有一种组合: 两个Rand5()都生成1时:(1, 1);而生成2有两种:(1, 2)和(2, 1);生成6更多。 它们的生成是不等概率的。那要怎样找到一个等概率生成数的组合呢?
我们先给出一个组合,再来进行分析。组合如下:5 * (Rand5() - 1) + Rand5()
Rand5产生1到5的数,减1就产生0到4的数,乘以5后可以产生的数是:0,5,10,15,20。 再加上第二个Rand5()产生的1,2,3,4,5。我们可以得到1到25, 而且每个数都只由一种组合得到,即上述代码可以等概率地生成1到25。OK, 到这基本上也就解决了。
套用上面的模板,我们可以得到如下代码:
int Rand7(){
int x = ~(1<<31); // max int
while(x > 7)
x = 5 * (Rand5() - 1) + Rand5() // Rand25
return x;
}
有两个杯⼦,容量分别为 5 升和 3 升,⽔的供应不断。问怎么⽤这两个杯⼦得到 4 升的⽔。
赛马问题
对于赛马问题的假设,可能是25匹马,5个赛道。或者是64匹马8个赛道。
对于后者来说可以参考这个分享: https://zhuanlan.zhihu.com/p/103572219
对于前者来说这这里简单进行说明:
1. 先将25匹马分成5组,进行5场赛马,得到每组的排名。
2. 将每组的第一名选出来单独进行一场比赛,按照这一场比赛中每匹马的位次,为他们初赛的分组进行排序,五组先后分别标记为A、B、C、D、E。
3. 已知,A组的第1名,就是25匹马的第一名。而全局第2、3名只可能在A组的2、3名,B组的1、2名,和C组的第一名,总共五匹马。
4. 让上述提到的五匹马进行1场赛马,前两名就是2,3名。
共计需要7场赛马
给定两条绳子,每条烧完正好一个小时,并且两条绳子是不均匀的。怎样利用这两条绳子准确测量15分钟?
答:
1. 点燃第一条绳子L1两头的同时,点燃另一条绳子L2的一端
2. 当L1燃烧完毕,过去30min的时间,此时L2还能再烧30min
3. 此时点燃L2的另一端,15min结束,L2烧完
想象你在镜子前,为什么镜子中的影像可以左右点到,却不能上下颠倒?
答:
因为人的两眼在水平方向上对称。
连续整数之和为1000的共有几组?
答:
等差数列、数学公式不易理解,我们来个容易理解的。
首先,最小的两个连续正整数相加1+2=3,大点的就是2+3=5=1+2+2,再大点3+4=7=2+3+2=1+2+(2+2),从中可以看出如果存在两个连续正整数之和等于N,那么必然N=1+2+2k(k为正整数),N-(1+2)可以整除2,即(N-(1+2))%2 == 0.
往下推,n个连续正整数就是,(N-(1+2+...+n))%n == 0```Java
class Solution {
public int consecutiveNumbersSum(int N) {
int result = 1;
int sum = 1;
//一个连续正整数即N本身,我们从2开始逐一判断,true则加1
for (int i=2; (sum+=i)<=N; i++) {
if ((N-sum)%i == 0) {
result++;
}
}
return result;
}
}```
作者:shi-san-dao
链接:https://leetcode.cn/problems/consecutive-numbers-sum/solution/829zhao-gui-lu-jian-dan-yi-li-jie-by-shi-san-dao/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。