Redian新闻
>
问一道微软的面试题-被难到了。
avatar
问一道微软的面试题-被难到了。# JobHunting - 待字闺中
h*2
1
问一道微软的面试题:
有2*N个文件,文件的大小保存在size[2*N]中。然后想要分成N份(每一份可以有1或者
多个文件),要使这N份中的文件size之和的最大值最小,如何实现?
avatar
w*x
2
没看明白, 怎么分size都不变啊
avatar
s*r
3
This is similar to Huffman-code. Put the size array into
a min-priority queue. Pick the top2, add them and put the sum
back into the priority queue, until there are N elements left.

【在 h******2 的大作中提到】
: 问一道微软的面试题:
: 有2*N个文件,文件的大小保存在size[2*N]中。然后想要分成N份(每一份可以有1或者
: 多个文件),要使这N份中的文件size之和的最大值最小,如何实现?

avatar
n*w
4
lz有没有例子?不太懂题目。但是感觉不是贪心就是DP。
avatar
j*e
5
这是greedy的做法,不能保证最优吧.
例如1, 2, 3, 6, 7分两组,这样做的结果会得到(1,2,3,6), (7)吧?
当然,这肯定是个NP问题,这个greedy解法也不错了,应该能保证
是2/1-aprroximation了。

【在 s****r 的大作中提到】
: This is similar to Huffman-code. Put the size array into
: a min-priority queue. Pick the top2, add them and put the sum
: back into the priority queue, until there are N elements left.

avatar
w*x
6
只能想到greedy啊~~
avatar
b*e
7
This is equivalent to partition or knapsack.

【在 h******2 的大作中提到】
: 问一道微软的面试题:
: 有2*N个文件,文件的大小保存在size[2*N]中。然后想要分成N份(每一份可以有1或者
: 多个文件),要使这N份中的文件size之和的最大值最小,如何实现?

avatar
l*i
8
没看明白 怎么分size不是都不变么?
avatar
d*f
9
N份中的文件size之和的最大值最小

【在 l****i 的大作中提到】
: 没看明白 怎么分size不是都不变么?
avatar
m*d
10
size从大到小排列,每次把文件放到当前文件和最小的组里。1, 2, 3, 6, 7分两组的
情况:
1)7
2)7,6
3)7,6 3
4)7 2,6 3
5)7 2 1, 6 3
用heap找文件和最小值。
avatar
r*g
11
没明白lz的意思是把2N份文件文成N份,还是分成2份。。

【在 m******d 的大作中提到】
: size从大到小排列,每次把文件放到当前文件和最小的组里。1, 2, 3, 6, 7分两组的
: 情况:
: 1)7
: 2)7,6
: 3)7,6 3
: 4)7 2,6 3
: 5)7 2 1, 6 3
: 用heap找文件和最小值。

avatar
E*0
12
我觉得是正解。

【在 s****r 的大作中提到】
: This is similar to Huffman-code. Put the size array into
: a min-priority queue. Pick the top2, add them and put the sum
: back into the priority queue, until there are N elements left.

avatar
w*x
13

So do 偶

【在 E*******0 的大作中提到】
: 我觉得是正解。
avatar
E*0
14
Sorry, I found it is not correct.
Counter example:
2,4,4,5
1st step: 4, 5, 6
2st step: 6, 9
which maximum file size is 9.
but we can found (2,5) and (4,4) with smaller maximum file size of 8.

【在 w****x 的大作中提到】
:
: So do 偶

avatar
E*0
15
result should be bigger than or equal to 2*average of (2*N array).
avatar
l*3
16
the first step result should be 2, 8, 5

【在 E*******0 的大作中提到】
: Sorry, I found it is not correct.
: Counter example:
: 2,4,4,5
: 1st step: 4, 5, 6
: 2st step: 6, 9
: which maximum file size is 9.
: but we can found (2,5) and (4,4) with smaller maximum file size of 8.

avatar
h*2
17
能具体解释一下吗?

【在 b***e 的大作中提到】
: This is equivalent to partition or knapsack.
avatar
E*0
18
why?

【在 l****3 的大作中提到】
: the first step result should be 2, 8, 5
avatar
l*3
19
from 2 4 4 5
pick 5, now we have 5 0
pick 4, now we have 5 4
pick 4, now we have 5 8
pick 2, now 7 8
....

【在 E*******0 的大作中提到】
: why?
avatar
E*0
20
Would you please write your solution for 25, 13,12,7,7,7 and 25,24,23,1,1,1
respectively?
And [slower]'s algorithms is for min-priority queue.

【在 l****3 的大作中提到】
: from 2 4 4 5
: pick 5, now we have 5 0
: pick 4, now we have 5 4
: pick 4, now we have 5 8
: pick 2, now 7 8
: ....

avatar
b*e
21
Assuming you have 2*n items, the sum of which is S. Then you can add
2000000 * n items, each of which is of value S/4. This way you are pretty
much bound to divide the S into two halfs, which is a partition/knapsack
problem.

【在 h******2 的大作中提到】
: 能具体解释一下吗?
avatar
s*t
22
先sorting一下,首跟尾一组,然后把首跟尾去掉,再把首跟尾一组,递归。。。。
avatar
s*t
23
32
26

1

【在 E*******0 的大作中提到】
: Would you please write your solution for 25, 13,12,7,7,7 and 25,24,23,1,1,1
: respectively?
: And [slower]'s algorithms is for min-priority queue.

avatar
c*d
24
1 2 3 7 就不对
好像只有megamind的解法靠谱

【在 s******t 的大作中提到】
: 先sorting一下,首跟尾一组,然后把首跟尾去掉,再把首跟尾一组,递归。。。。
avatar
m*k
25
25
25, 13
25,13,12
25,13, 12+7
25, 13+7, 12+7
25, 13+7, 12+7+7
我也觉得megamind的解法靠谱,求证明。

1

【在 E*******0 的大作中提到】
: Would you please write your solution for 25, 13,12,7,7,7 and 25,24,23,1,1,1
: respectively?
: And [slower]'s algorithms is for min-priority queue.

avatar
E*0
26
举个反例:
25, 25, 19, 15, 14, 13, 12, 11,10, 1
正解: 25, 25, (13,12), (14,11),(15,10), (19,1)
按照megamind的算法:
1) 25,25,19,15,14
2) 25, 25, 19, 15, (14,13)
3) (14,13), 25, 25, 19, (15, 12)
4) (14,13), (15,12), 25,25, (19,11)
5) (19,11), (14,13), (15,12), (25,10), 25
6) (19,11), (14,13), (15,12), (25,10), (25,1)

【在 m******d 的大作中提到】
: size从大到小排列,每次把文件放到当前文件和最小的组里。1, 2, 3, 6, 7分两组的
: 情况:
: 1)7
: 2)7,6
: 3)7,6 3
: 4)7 2,6 3
: 5)7 2 1, 6 3
: 用heap找文件和最小值。

avatar
E*0
27
我目前还没有找到一个方法解决这个问题。
我有一些基本的clue供大家参考:
1,如果2*N个数都相等的话,Min(Sum)=2*val;
2,如果2*N个数有一个特别大,其大都很小,Min(sum)=max value;
3,如果2*N个数是[1,2,3,...,N,N+1, ..., 2*N], Min(Sum)=2*N+1=2* average.
avatar
E*0
28
2, 第三种情况分组分别是头尾相连。
3, 但是还有一种情况是,刚好三个三个为一组,组成平均数,还有若干个平均数数值。
4, 刚好四个四个为一组,组成平均数,还有若干个平均数。
5, 刚好五个五个为一组,组成平均数,还有若干个平均数。
依此类推,越来越发现这个问题是NP问题,不知道大家有什么看法。
avatar
E*0
29
我有一个假设:
Min(sum)>=Max[2*average, MaxValu];
int goal=Max[2*average, MaxValu];
同样排序,用greedy algorithm找到尽可能多的组合which sum equals goal.
avatar
E*0
30
大家再看看这个人说的,貌似有点道理,我再想想啊。

【在 b***e 的大作中提到】
: Assuming you have 2*n items, the sum of which is S. Then you can add
: 2000000 * n items, each of which is of value S/4. This way you are pretty
: much bound to divide the S into two halfs, which is a partition/knapsack
: problem.

avatar
t*e
31
这个反例不对吧,没有把文件分为5组。是不是应该下面这样?
(25) (25,1) (15, 14) (12, 11, 10) (13, 19)
这题只能想到状态压缩DP解法。

【在 E*******0 的大作中提到】
: 举个反例:
: 25, 25, 19, 15, 14, 13, 12, 11,10, 1
: 正解: 25, 25, (13,12), (14,11),(15,10), (19,1)
: 按照megamind的算法:
: 1) 25,25,19,15,14
: 2) 25, 25, 19, 15, (14,13)
: 3) (14,13), 25, 25, 19, (15, 12)
: 4) (14,13), (15,12), 25,25, (19,11)
: 5) (19,11), (14,13), (15,12), (25,10), 25
: 6) (19,11), (14,13), (15,12), (25,10), (25,1)

avatar
t*e
32
写个思路抛砖引玉了。
a[2*N]表示文件大小数组,设f(int[] a, int set, int k)表示状态,set是一个
binary integer表示a[]的一个子集,k表示将a[]的这个子集分成k份,状态转移方程是
f(a[], set, k) = min{ max{sum(a[]: for element a[i] in a subset set' of set
), f(a, set - set', k-1)}: for all subset set' of set }. 边界条件是f(a[],
set, 1) = sum(a[]: for elements a[i] in set). 解法的限制是N不能太大(<=10),
否则内存吃不消。
avatar
E*0
33
不好意思,搞错了。
就是说正解和那个算法解不一样。

【在 t******e 的大作中提到】
: 这个反例不对吧,没有把文件分为5组。是不是应该下面这样?
: (25) (25,1) (15, 14) (12, 11, 10) (13, 19)
: 这题只能想到状态压缩DP解法。

avatar
E*0
34
能否写的详细点?

set

【在 t******e 的大作中提到】
: 写个思路抛砖引玉了。
: a[2*N]表示文件大小数组,设f(int[] a, int set, int k)表示状态,set是一个
: binary integer表示a[]的一个子集,k表示将a[]的这个子集分成k份,状态转移方程是
: f(a[], set, k) = min{ max{sum(a[]: for element a[i] in a subset set' of set
: ), f(a, set - set', k-1)}: for all subset set' of set }. 边界条件是f(a[],
: set, 1) = sum(a[]: for elements a[i] in set). 解法的限制是N不能太大(<=10),
: 否则内存吃不消。

avatar
g*s
35
这个解法是指数级别的
DP很少会用subset作为状态。

【在 E*******0 的大作中提到】
: 能否写的详细点?
:
: set

avatar
f*2
36
This idea works. I illustrate in a slightly different way and hope it can be
easily understood.
Assume that we need to group 1, 2, 3, 6, 7 by two groups.
(1) In the very beginning, separate the biggest two numbers into different
groups.
Group 1: 7
Group 2: 6
(2) Next, we add 3 to one of the above groups. It is clear that 3 should be
added to 6, otherwise, if we had added 3 to 7, the sum would have changed to
10, not as optimal as 6 + 3 = 9.
Group 1: 7
Group 2: 6 + 3 = 9
(3) Add 2 to one of the above groups.Now Group 1 has smaller sum, so add 2
to the smallest group.
Group 1: 7 + 2 = 9
Group 2: 6 + 3 = 9.
(4) Add 1 to one of the above groups. Since both group has value 9, number 1
can be added to either one of them. So the result turns to be
Group 1: 7 + 2 + 1 = 10
Group 1: 6 + 3 = 9.
Answer: 10
Example 2: Divide 25,13,12,7,7,7 into three groups (from Erica3740 (秋泥针))
(Step 1) Initialize the three groups with the biggest three numbers.
Group 1: 25
Group 2: 13
Group 3: 12
(Step 2) Add 7 to one of the above groups. Group 3 has the smallest element
and so is the best choice.After addition, we have
Group 1: 25
Group 3: 12 + 7 = 19
Group 2: 13
(Step 3) Add 7 to one group. Group 2 has the smallest element and so is the
best choice.
Group 1: 25
Group 3: 12 + 7 = 19
Group 2: 13 + 7 = 20
(Step 4) Add 7 to one group. Group 3 has the smallest element and so is the
best choice.
Group 1: 25
Group 3: 12 + 7 + 7 = 19 + 7 = 26
Group 2: 13 + 7 = 20
Answer: 26
Example 3: Divide 25,24,23,1,1,1 into 3 groups
25
24 + 1 = 25
23 + 1 + 1 = 25
Answer: 25

【在 m******d 的大作中提到】
: size从大到小排列,每次把文件放到当前文件和最小的组里。1, 2, 3, 6, 7分两组的
: 情况:
: 1)7
: 2)7,6
: 3)7,6 3
: 4)7 2,6 3
: 5)7 2 1, 6 3
: 用heap找文件和最小值。

avatar
b*e
37
用这个原理:假设数组a[n] is sorted. 则最优解发生于下列两情况之一:1. a[n-1]
单独组成一份 2. a[n-1] 与 a[0] 组成一份。
由上可得递归算法如下:
int minUnit(int a[], int n, int nUnit)
{
if(n == 1)
return a[0];
if(nUnit == 1)
return SUM(a, n);
int min1 = MAX(a[n-1], minUnit(a, n-1, nUnit-1)); // a[n-1]单独一份
int min2 = MAX(a[n-1]+a[0], minUnit(a+1, n-2, nUnit-1)); // a[n-1] 与 a[
0] 组成一份
return MIN(min1, min2);
}
avatar
l*o
38
25 13 12 7 7 7结果应该是
25 (13 12)(7 7 7)
这个解法是错的

be
be
to
★ 发自iPhone App: ChineseWeb 7.3

【在 f*********2 的大作中提到】
: This idea works. I illustrate in a slightly different way and hope it can be
: easily understood.
: Assume that we need to group 1, 2, 3, 6, 7 by two groups.
: (1) In the very beginning, separate the biggest two numbers into different
: groups.
: Group 1: 7
: Group 2: 6
: (2) Next, we add 3 to one of the above groups. It is clear that 3 should be
: added to 6, otherwise, if we had added 3 to 7, the sum would have changed to
: 10, not as optimal as 6 + 3 = 9.

avatar
c*d
39
提供一个想法,我暂时还没想到反例:
假设我们有N个bag来装这2N个数,首先将N个bag全部初始化为0, 用一个max变量实时
记录这N个bag的最大的那个, 将2N个数字从大到小排列,然后按照如下规则将这个2N个
数一个一个装袋:
case 1: 从最大的bag开始search,找到第一个这样的bag:满足这个bag的和加上这个
数不大于现在的max,如果能找到这个bag,就把这个数装到这个bag里面。
case 2: 找不到这样的bag,这说明已经search到最后那个最小的bag了(并且这个也不
满足case1的条件),如果这样的话,就将现在这个数加入这个bag,并且更新max为这个
bag的值。
example: 25 13 12 7 7 7
bags: 0 0 0, max = 0.
25: 25 0 0, max = 25. (case 2)
13: 25 13 0, max = 25. (case 1)
12: 25 (13,12) 0, max = 25. (case 1)
7: 25 (13,12) 7, max = 25. (case 1)
7: 25 (13,12) (7,7), max = 25 (case 1)
7: 25 (13,12) (7,7,7)max = 25 (case 1)
avatar
o*d
40
感觉是DP啊,考虑最大的一个文件,假设这个大小是a,那么可以知道只有两种情况:a
可能是单独的一个文件为一组,也可能是两个文件为一组。
如果包含a的那一组有3个文件(a,b,c),那么必然有一个文件d(d显然a+b+c>a+b, a+b+c>d+c
如果a的那一组有两个文件(a,b),并且b不是最小的,那么假设c为最小,如果包含c的
一组文件数大于2,那么一定有一个文件d单独为一组,那么如果交换a和d,可以知道a+b
>a,a+b>b+d.所以这种情况可以转化为a单独一组,
如果包含c的一组文件有两个(c,d)那么我们可以知道b>c,a>d,显然这样不是最优的,
如果c单独为一组,那么显然也有a+b>a+c,a+b>b
假设为排序序列的话,那么是不是就有opt(i,j)=min(max(size(i),opt(i,j-1)),max(
size(i)+size(j),opt(i+1,j-1)))?

【在 h******2 的大作中提到】
: 问一道微软的面试题:
: 有2*N个文件,文件的大小保存在size[2*N]中。然后想要分成N份(每一份可以有1或者
: 多个文件),要使这N份中的文件size之和的最大值最小,如何实现?

avatar
l*o
41
参考31楼给的例子,是不是有点问题。

★ 发自iPhone App: ChineseWeb 7.3

【在 c*******d 的大作中提到】
: 提供一个想法,我暂时还没想到反例:
: 假设我们有N个bag来装这2N个数,首先将N个bag全部初始化为0, 用一个max变量实时
: 记录这N个bag的最大的那个, 将2N个数字从大到小排列,然后按照如下规则将这个2N个
: 数一个一个装袋:
: case 1: 从最大的bag开始search,找到第一个这样的bag:满足这个bag的和加上这个
: 数不大于现在的max,如果能找到这个bag,就把这个数装到这个bag里面。
: case 2: 找不到这样的bag,这说明已经search到最后那个最小的bag了(并且这个也不
: 满足case1的条件),如果这样的话,就将现在这个数加入这个bag,并且更新max为这个
: bag的值。
: example: 25 13 12 7 7 7

相关阅读
logo
联系我们隐私协议©2024 redian.news
Redian新闻
Redian.news刊载任何文章,不代表同意其说法或描述,仅为提供更多信息,也不构成任何建议。文章信息的合法性及真实性由其作者负责,与Redian.news及其运营公司无关。欢迎投稿,如发现稿件侵权,或作者不愿在本网发表文章,请版权拥有者通知本网处理。