Let's call any (contiguous) subarray B (of A) a mountain if the following properties hold:
B.length >= 3
- There exists some
0 < i < B.length - 1
such thatB[0] < B[1] < ... B[i-1] < B[i] > B[i+1] > ... > B[B.length - 1]
(Note that B could be any subarray of A, including the entire array A.)
Given an array A
of integers, return the length of the longest mountain.
Return 0
if there is no mountain.
Example 1:
Input: [2,1,4,7,3,2,5] Output: 5 Explanation: The largest mountain is [1,4,7,3,2] which has length 5.
Example 2:
Input: [2,2,2] Output: 0 Explanation: There is no mountain.
Note:
0 <= A.length <= 10000
0 <= A[i] <= 10000
题目是求一个连续列表的满足题目中条件的山峰数组条件的最长长度。
我考虑将定义一个类用来表述上坡、下坡、平滑段,然后将整个列表进行分段,然后再对分段数组进行判断,如果前一段是上坡,下一段是下坡,则当前为山峰数组段。最后找所有满足这种条件的山峰数组的长度的最大值。Python代码实现
# 定义一个类,用来定义当前的数据的状态,上坡、下坡、平滑
class upOrDownList:
# 0 代表向下
# 1 代表向上
# -1 代表平等
def __init__(self, n):
self.isUp = n
self.lst = []
class Solution:
def longestMountain(self, A):
"""
:type A: List[int]
:rtype: int
"""
L = len(A)
if L < 3:
return 0
# 保存最后的上坡、下坡或平滑的段列表
partlist = []
# 初始化状态列表
upLst = upOrDownList(1)
downLst = upOrDownList(0)
smoothLst = upOrDownList(-1)
for i in range(1,L):
# 当前上坡
if A[i] > A[i-1]:
# 判断上次状态
# 下坡
if len(downLst.lst) != 0:
partlist.append(downLst)
# 每次改变完状态,重新初始化新的三个列表状态
upLst = upOrDownList(1)
downLst = upOrDownList(0)
smoothLst = upOrDownList(-1)
# 平滑
elif len(smoothLst.lst) != 0:
partlist.append(smoothLst)
upLst = upOrDownList(1)
downLst = upOrDownList(0)
smoothLst = upOrDownList(-1)
# if i == 1:
# upLst.lst.append(A[i-1])
# 为了保持统一,第一个点未加到列表中
upLst.lst.append(A[i])
# 当前下坡
elif A[i] < A[i-1]:
if len(upLst.lst) != 0:
partlist.append(upLst)
upLst = upOrDownList(1)
downLst = upOrDownList(0)
smoothLst = upOrDownList(-1)
elif len(smoothLst.lst) != 0:
partlist.append(smoothLst)
upLst = upOrDownList(1)
downLst = upOrDownList(0)
smoothLst = upOrDownList(-1)
# if i == 1:
# downLst.lst.append(A[i-1])
downLst.lst.append(A[i])
# 当前平滑
else:
if len(upLst.lst) != 0:
partlist.append(upLst)
upLst = upOrDownList(1)
downLst = upOrDownList(0)
smoothLst = upOrDownList(-1)
elif len(downLst.lst) != 0:
partlist.append(downLst)
upLst = upOrDownList(1)
downLst = upOrDownList(0)
smoothLst = upOrDownList(-1)
# if i == 1:
# smoothLst.lst.append(A[i-1])
smoothLst.lst.append(A[i])
# 最后一小段添加到段列表
if len(upLst.lst) != 0:
partlist.append(upLst)
if len(downLst.lst) != 0:
partlist.append(downLst)
if len(smoothLst.lst) != 0:
partlist.append(smoothLst)
# result
# 段列表至少两段才能表示山谷
if len(partlist) < 2:
return 0
maxL = 0
for i in range(1,len(partlist)):
first = partlist[i-1].isUp
second = partlist[i].isUp
# 当前段和前一段分别为上坡、下坡
if first == 1 and second == 0:
maxL = max(maxL, len(partlist[i-1].lst)+len(partlist[i].lst)+1) #转折点的起始点未添加到下一段,所以计算长度需要加一
return maxL
s = Solution()
print(s.longestMountain([0,1,2,3,4,5,4,3,2,1,0]))
PS,如果转化为山谷列表,则很容易,直接对最后的判断形式改成:如果上一段是下坡,下一段是上坡就行了。所以采用分块思想处理时,修改比较简单。