您的位置:首页 > 其它

【算法题汇总(每天进步一点点)——持续更新中】

2015-07-19 23:54 507 查看
2015.07.19

1. hulu面试题

【参考】
http://blog.csdn.net/v_july_v/article/details/7974418 http://www.51nod.com/question/index.html#!questionId=642
【100个人,每人头上戴一顶帽子,写有0~99的一个数,数可能重复,每个人都只能看到除自己以外其他人的帽子。每个人需要说出自己的帽子的数,一个人说对就算赢。】

分析:

一、每个人猜数都是相互独立的,不会互相影响

题中只要有一个人对即算赢,那么考虑其对立事件【所有人都没对】,即:100个人,每个人都没猜对自己帽子对应的数,这样每个人说的数都有99种可能(除了自己帽子对应的数外),而每个人猜数独立,因此:

P(输) = P(所有人都猜错) = (99/100)^100

P(赢) = 1 - P(输) = 1 - (99/100)^100【这个数字几乎
= 1】

二、每个人猜数都可以参考其他人帽子上的数字

这时100个人中按照下述的策略必定有人会猜对。

解析:100个人编号为0-99,每个人可看到其他人帽子上的数。

对于编号为 i 人,将其他人帽子上的数累加

然后mod 100,设余数结果为k

则这个人猜自己帽子上的数为(i
- k + 100) mod 100 即可。

注:所有帽子数字累加和 mod 100的结果取值为0
- 99。

2. 搜狗面试题

一个长度为n的数组a[0],a[1],...,a[n-1]。现在更新数组的名个元素,即a[0]变为a[1]到a[n-1]的积

a[1]变为a[0]和a[2]到a[n-1]的积,...,a[n-1]为a[0]到a[n-2]的积。

程序要求:

要求具有线性复杂度。

不能使用除法运算符。

分析:

由于不能使用除法,因此不能考虑循环2次的算法(而且此时的时间复杂度也不是线性的)

可以按照以下思路考虑:

定义临时数组,从右至左存储对应数组后面所有元素的乘积;

e.g:

a[0-N-1] 临时数组为temp[0-N-1]

temp[N-1]=a[N-1]

temp[N-2]=a[N-1]

temp[N-3]=a[N-1]*a[N-2]

...

temp[1]
= a[N-1]*a[N-2]*...*a[2]

temp[0]
= a[N-1]*a[N-2]*...*a[1]

接下来对原数组从左向右遍历,并定义一个临时变量tmp(保存的是原数组当前元素及前面所有元素的乘积)

而temp数组保存的是原数组当前元素后面所有的元素,两者相乘即可得除当前元素外所有元素的乘积。

实现代码如下:

#include <iostream>

using namespace std;

void printArr(int* a, int len)
{
for (int i = 0; i < len; ++i)
{
cout<<a[i]<<" ";
}

cout<<endl;
}

void updateArr(int* a, int len)
{
int* temp = new int[len];
int tmp;
temp[len - 1] = a[len - 1];
temp[len - 2] = a[len - 1];
for (int i = len - 3; i >= 0; --i)
{
temp[i] = a[i + 1] * temp[i + 1];
}
tmp = a[0];
a[0] = temp[0];
for (int i = 1; i < len - 1; ++i)
{
temp[i] *= tmp;
tmp *= a[i];
a[i] = temp[i];
}
a[len - 1] = tmp;
}

int main(void)
{
int a[] = {1, 2, 3, 4, 5, 3};
int len = sizeof(a) / sizeof(int);

updateArr(a, len);

printArr(a, len);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: