合唱队的N名学生站成一排依次编号为1-N,先要求在编号连续的前提下,将学生按照身高进行分组,要求每组的最矮的同学要比上一组最高的同学要高或者相等。问最大可以分成几组。
输入:
第一行: 人数
第二行: 每个人的身高
输出:
最大的分组数
如:
输入:
4
2 1 3 2
输出:
2
解释:
[2,1,3,2]->[[2,1], [3,2]]
解题思路: 遍历数组,记录当前区间的最大值与最小值。
- 如果下一个值大于当前区间的最大值,那么就可以新开一个区间,并将上一个区间存下来;
- 如果下一个值小于当前区间的最小值,却大于上一个区间的最大值,那么更新当前区间的最小值;
- 如果下一个值甚至小于上一个区间的最大值,那么就往前遍历之前存储的区间,直到找到合适区间进行合并。
# -*- coding: utf-8 -*-
'''
京东笔试题:
给定一个数组,求数组最大可以分成多少个子数组。
相邻子数要满足上一个子数组的最大值要小于或等于下一个子数组的最小值。
如a = [2, 1, 3, 2]可以分为:[[2, 1], [3, 2]]
'''
def maxGroup(n, A):
area = [[A[0], A[0]]]
for i in range(1, n):
# 如果当前值大于当前区间的最大值,记录区间信息,并新开一个区间
if A[i] >= area[-1][1]:
area.append([A[i], A[i]])
else:
# 当前值小于当前区间最大值
if len(area) > 1 and A[i] >= area[-2][1]: # 大于上一个区间的最大值
# 更新当前区间
area[-1][0] = min(area[-1][0], A[i])
else: # 比上一个区间的最大值小,开始寻找其合适的区间进行合并
maxValue = area[-1][1]
while area:
temp = area.pop(-1)
if A[i] >= temp[0]:
area.append([temp[0], maxValue])
break
if len(area) == 0:
area.append([A[i], maxValue])
print(area)
return len(area)
if __name__ == '__main__':
A = [2, 1, 3, 2, 4, 7, 6, 2]
n = len(A)
print(maxGroup(n, A))