题目:
牛牛有一个n个数字的序列,现在牛牛想把这个序列分成k段连续段,牛牛想知道分出来的k个连续段的段内数字和的最小值最大可以是多少?
示例1:
数列:[1,2,1,5],长度为4;k = 2
结果:4
具体分法有3种,如下:
[1],[2,1,5],数字和分别为1,8,最小值为1
[1,2][1,5],数字和分别为3,6,最小值为3
[1,2,1],[5]数字和分别为4,5,最小值为4
则最小值的最大值为4
答案:
思路解析:
首先明白我们要找的这个值一定是处于[0,sum(a)]这个区间的一个值,但具体是多少不知道.
那么我们首先可以判断mid1 = sum(a)/2这个值能不能划分出大于等于k个组,
如果可以那么我们其实可以缩小区间至[mid1,sum(a)],再次判断mid2 = (sum(a)+mid1)/2 能否得到k个组.如果不可以,那自然的,只能将区间改写为[mid1,mid2],
依次循环直到某一时刻.我们找到一个能将整个组划分为k个且对应区间的左右两端差值极小.(理论上小于1就可以.)
那么这个时候,自然的我们就找到了对应可以划分出来的数字和的最大最小值.(均分情况下明显最小值会大于别的情况嘛~)。
所以,这道题的本质还是考察面试者对于二分法的理解
具体代码如下:
def max_sum_group(k, a):
x, y = 0, sum(a)
if k == 1:
return y
while y - x > 1:
mid = (x + y) / 2
segment = 0
nowval = 0
for i in range(len(a)):
nowval += a[i]
if nowval >= mid:
segment += 1
nowval = 0
if segment >= k:
x = mid
else:
y = mid
return round((x + y) / 2)
if __name__ == '__main__':
k = 2
a = [1, 2, 1, 5]
ret = max_sum_group(k, a)
print(ret)