题目描述
给定一个数组A,将其划分为两个不想交(没有公共元素)的连续子数组left和right,使得
1)left 中的每个元素都小于等于 right 中的每个元素;
2)left 和 right 非空;
3)left 要尽可能小;
最后返回 left 的长度。
例如: 输入[5, 0, 3, 8, 6] ----->输出 3
因为 left = [5, 0, 3], right = [8, 6]
分析
题目大致意思是,将一个数组中间切一刀,使得左边部分的最大值小于右边部分的最小值。
那是不是可以这样,对数组进行遍历,当左边的最大值小于右边的最小值就输出当前的位置?答案是不可以的,在Python中虽然max()和min()函数很好用,但是它们本质上也是一次遍历,只不过对使用者透明,使用的话会超出时间限制。
那该怎么办呢?
假设left的长度为1,并且该元素设为左边部分的最大值lm,那么right就为剩下的n-1。我们可以对剩下的n-1遍历,遍历时假如当前元素小于lm(不满足条件1),说明这个元素一定属于left,那么就要把“刀”移到当前位置。但是还要注意,移动“刀”位置后,left部分的最大值lm可能会发生变化,因此需要在遍历时记录最大元素,以便及时更新lm。
代码
class Solution(object):
def partitionDisjoint(self,A):
"""
:type A:List[int]
:rtype:int
"""
# l代表那把刀
l = 1
lm = A[0]
maxItem = A[0]
n = len(A)
for i in range(l,n):
if A[i] < lm:
l = i + 1
lm = maxItem
if A[i] > maxItem:
maxItem = A[i]
return l