关注我们,每周发布最新的笔面试题目和解析
记得设为星标哦
面向研究类的笔试题目,主要是数理统计和编程题,限时60min,一共6个题,下面给出其中的四题,更全的试题在知识星球中获取.整体难度不大,和之前发布的题目有相似的地方,好好准备!
由于后台收到相关公司人员留言,后续推送标题中将不再指明具体公司名称,具体公司将在知识星球中公布。
春招和暑期实习和笔试也陆陆续续开始了,欢迎同学们在公众号后台投稿,你们的每条留言小编都会仔细查看。累计投稿4场将获得知识星球100元优惠券,也可原价直接加入。更全的笔面试资料及学习路线在知识星球中,会随着资源的积累不断涨价,早加入早学习早拿offer!
有4个人玩一个游戏,4个人每人自成一个组,裁判随机抽取两个人石头剪刀布(无平局),输的那一方整个组加入另一个组,直到全部人属于同一个组,求游戏结束的最小抽取次数以及期望抽取次数。
【答案】
最小抽取次数: 3次
期望抽取次数: 略大于3次
【思路】
最小抽取次数
在最佳情况下,每次抽取都会导致两个不同组合并。初始有4个独立组,每次合并将减少一个组:
第一次抽取后,组数从4减至3。
第二次抽取后,组数从3减至2。
第三次抽取后,组数从2减至1,游戏结束。
因此,游戏结束的最小抽取次数是3次。
期望抽取次数
期望抽取次数依赖于每次抽取时,被选择的两人是否来自不同的组。对于四人来说,初始时任意两人都来自不同的组,因此首次抽取一定是有效的。随后的抽取中,虽然可能性复杂,但因为人数较少,平均情况下的抽取次数仍然接近3次。具体的计算会涉及到概率论中更复杂的组合概率计算,但在实际情况下,期望抽取次数略高于3次,因为存在已经是同一组的人被重复抽取的可能性。
总的来说,每次操作都必须有效地减少组的数量以朝向游戏结束,这样的期望次数计算依赖于各种情况下选中来自不同组的两个人的概率。在4个人的情况下,这个计算比较简单,期望次数略大于3次,具体值的计算则需要详细的概率分析。
你的汤碗里有 100 条面条。你被蒙住眼睛,被告知在你的碗里拿出一些面条的两端(任何面条的每一端都有相同的被选中的概率),并将它们连接起来。直到没有空闲的末端为止。面条以这种方式形成的圈的数量是随机的。计算期望的圆数。
【思路】随机配对问题
每次连接可以看作是在随机选择一个还未配对的末端,并找到另一个末端与之配对。当你随机连接这些末端时,形成的圈的数量将会是一个随机变量。每次连接时,你都有可能开始形成一个新的圈,或者继续扩展一个已经开始形成的圈。数学上,这可以通过一个递归关系进行分析:
每次连接时形成新圈的概率:假设你已经有 𝑛n 个末端已经配对。那么选择下一个末端并找到与之配对的末端形成一个新的圈的概率是 1/(𝑛−1)。
使用递归计算期望:设 𝐸(𝑛)是当有 n个末端时形成的圈的期望数量。对于任何一个给定的步骤,选择下一个末端,你都有一个末端以 1/(𝑛−1)的概率立即闭合一个圈,而 (𝑛−2)/(𝑛−1)的概率不会闭合圈。因此,期望的圈数递归公式为:
𝐸(𝑛)=1+𝐸(𝑛−2)
其中 𝐸(0)=0,因为没有末端时没有圈。
基于上述递归公式,计算 E(200):可以发现 𝐸(𝑛)E(n) 随 𝑛n 线性增长,因为每两个末端配对减少一个末端对,从而增加一个期望的圈数。这意味着 𝐸(200)E(200) 等于 100(即连接次数),也就是最开始的面条数。
因此,期望的圈数是 100。这个结果表明,平均而言,每次连接操作都会产生一个新的圈,这反映了每次操作几乎总是在不断减少的未配对末端中创建新的圈。
甲乙两人投篮,每次由其中一人投篮,规则如下:若命中则此人继续投篮,若为命中则换为对方投篮。无论之前投篮情况如何,甲每次投篮的命中率均为0.6,乙每次投篮的命中率均为0.8,由抽签决定第一次投篮的人选,第一次投篮的人为甲/乙的概率均为0.5。
(1)求第2次投篮的人为乙的概率;
(2)求第次投篮的人为甲的概率;
(3)记前次投篮中,甲投篮的次数为,求E(Y)
【思路】
这个问题描述了一个随机交替的投篮游戏,其中甲和乙的命中率分别是0.6和0.8,而且甲和乙开始投篮的概率都是0.5。我们可以通过构建状态转移模型来解决这个问题。
(1) 求第2次投篮的人为乙的概率
如果甲开始投篮,第二次为乙投篮的情况只有一种可能,即甲未命中,其概率为 1−0.6=0.4。
如果乙开始投篮,第二次为乙投篮的情况只有一种可能,即乙命中后继续投篮,其概率为 0.8。
因此,第二次投篮的人为乙的概率为:𝑃(第2次投篮者为乙)=0.5×0.4+0.5×0.8=0.2+0.4=0.6
(2) 求第2次投篮的人为甲的概率
如果甲开始投篮,第二次为甲投篮的情况只有一种可能,即甲命中后继续投篮,其概率为 0.6。
如果乙开始投篮,第二次为甲投篮的情况只有一种可能,即乙未命中,其概率为 1−0.8=0.2。
因此,第二次投篮的人为甲的概率为:𝑃(第2次投篮者为甲)=0.5×0.6+0.5×0.2=0.3+0.1=0.4
(3) 记前次投篮中,甲投篮的次数为Y,求E(Y)
为了求出E(Y),即甲投篮次数的期望值,我们可以考虑在无限次投篮中,甲每次投篮的概率。
由于甲投篮命中后继续投篮的概率是0.6,而失误后换乙投篮,乙失误后再换回甲的概率是 0.2,因此我们可以列出甲获得再次投篮权的概率为:𝑃(甲继续投篮)=0.6+(1−0.6)×0.2=0.6+0.08=0.68
由于每次甲投篮结束后,甲再次投篮的概率是0.68,而乙投篮的概率是 1−0.68=0.32,因此长期下来甲和乙的投篮比例是0.68:0.32,甲的期望投篮次数比例为:𝐸(甲投篮次数比例)=0.68/(0.68+0.32)=0.68/1=0.68
因此,长期下来,甲的投篮次数期望值占总投篮次数的68%。这意味着在无限多次投篮中,甲投篮的期望次数为68%的总投篮次数。
算法(Python/C++): (1)请实现快速排序算法 (2)请实现树的层次遍历
【参考答案】
(1)
快速排序是一种分而治之的排序算法,它将数组分为两个子数组,将小于或等于枢轴元素的数据放到左边,大于枢轴元素的数据放到右边,然后对这两个子数组再递归进行相同的操作。
Python实现:
def quick\_sort(arr):
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quick\_sort(left) + middle + quick\_sort(right)
# 输入输出示例
arr = [3, 6, 8, 10, 1, 2, 1]
sorted\_arr = quick\_sort(arr)
print(sorted\_arr) # 输出: [1, 1, 2, 3, 6, 8, 10]
C++实现:
#include <iostream>
#include <vector>
#include <algorithm>
void quick\_sort(std::vector<int>& arr, int left, int right) {
if (left >= right) return;
int pivot = arr[(left + right) / 2];
int i = left, j = right;
while (i <= j) {
while (arr[i] < pivot) i++;
while (arr[j] > pivot) j--;
if (i <= j) {
std::swap(arr[i], arr[j]);
i++;
j--;
}
}
if (left < j) quick\_sort(arr, left, j);
if (i < right) quick\_sort(arr, i, right);
}
// 输入输出示例
int main() {
std::vector<int> arr = {3, 6, 8, 10, 1, 2, 1};
quick\_sort(arr, 0, arr.size() - 1);
for (int i : arr) {
std::cout << i << " "; // 输出: 1 1 2 3 6 8 10
}
return 0;
}
(2)
树的层次遍历,或称广度优先搜索(BFS),是一种遍历树结构的方法,从根节点开始,逐层访问树的每个节点,每层从左到右进行。
python实现:
class TreeNode:
def \_\_init\_\_(self, value):
self.val = value
self.left = None
self.right = None
def level\_order\_traversal(root):
if not root:
return []
queue = [root]
result = []
while queue:
current = queue.pop(0)
result.append(current.val)
if current.left:
queue.append(current.left)
if current.right:
queue.append(current.right)
return result
# 示例输入
root = TreeNode(1)
root.left = TreeNode(2)
root.right = TreeNode(3)
root.left.left = TreeNode(4)
root.left.right = TreeNode(5)
# 示例输出
print(level\_order\_traversal(root))
C++实现
#include <iostream>
#include <vector>
#include <queue>
class TreeNode {
public:
int val;
TreeNode \*left, \*right;
TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
};
std::vector<int> levelOrderTraversal(TreeNode\* root) {
std::vector<int> result;
if (!root) return result;
std::queue<TreeNode\*> queue;
queue.push(root);
while (!queue.empty()) {
TreeNode\* current = queue.front();
queue.pop();
result.push\_back(current->val);
if (current->left) queue.push(current->left);
if (current->right) queue.push(current->right);
}
return result;
}
int main() {
// 构建树
TreeNode\* root = new TreeNode(1);
root->left = new TreeNode(2);
root->right = new TreeNode(3);
root->left->left = new TreeNode(4);
root->left->right = new TreeNode(5);
// 执行层次遍历
std::vector<int> output = levelOrderTraversal(root);
for (int num : output) {
std::cout << num << " ";
}
std::cout << std::endl;
return 0;
}
思路或想法欢迎在留言区交流
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。