建信金科11/4笔试
第一题:链表的合并,如果是偶数,跟之前的合并。
ListNode* mergeNode(ListNode* head) {
// write code here
if (head == nullptr) return nullptr;
if (head->next == nullptr) return head;
auto prev = head; // 前置节点
auto curr = prev->next; // 下一个节点
// 如果节点是偶数值,准备从当前节点合并
if ((curr->val) % 2 == 0) {
// 这部分可能出错,因为合并的前提是前一个为奇数,当时做题没看到
// 这也是只A了80%的原因,交卷才反应过来
prev->val = (prev->val) + (curr->val);
auto temp = curr->next;
delete curr; // 删除该节点所占空间
prev->next = temp; // 连接起下一个节点
prev = mergeNode(prev); // 继续判断
}
// 如果是奇数值,则能从下一个点开始合并
else {
prev->next = mergeNode(curr);
}
return head;
}
第二题:删除链表的次数的期望
数学问题,概率乘次数,动态规划问题;
double get_expect(int n) {
// write code here
// if (n == 0) return 0;
// if (n == 1) return 1;
// if (n == 2) return 1;
// if (n == 3) {
// return (double)5 / 3;
// }
// double f1 = double(n - 2) / n;
// double f2 = 1 - f1;
// 递归版本的代码爆栈,超时,改为动态规划
// return f1 * get_expect(n - 3) + f2 * get_expect(n - 2) + 1;
vector<double> dp(n + 1);
if (n == 0) return 0;
if (n == 1) return 1;
if (n == 2) return 1;
if (n == 3) {
return (double)5 / 3;
}
dp[0] = 0;
dp[1] = 1;
dp[2] = 1;
dp[3] = (double)5 / 3;
for (int i = 4; i <= n; ++i) {
double f1 = double(i - 2) / i;
double f2 = 1 - f1;
dp[i] = f1 * dp[i - 3] + f2 * dp[i - 2] + 1;
}
return dp[n];
}
#建信金科#