我正在编写一个函数来查找给定列表中的所有山峰和山谷。例如,[1,0,0,0,1]返回3,[0,1,0,1,0]返回5. [0,2,2,1,1,0,0]返回3.如果数字(或具有相同值的连续数字)大于或小于其两个邻居,它被认为是山丘或山谷。
以下是我的代码:
def hill_and_vally(s):
if not s or len(s) < 2:
return 0
i = 0
count = 0
pre = None
while i < len(s):
if i == 0:
while s[i] == s[i+1]: # loop until value is different
i += 1
i += 1
if i < len(s): # check if it reaches the end
count += 1
pre = s[i-1] # track the previous value
elif i == len(s) - 1:
while s[i] == s[i-1]:
i -= 1
i -= 1
if i >= 0:
count += 1
break
else:
while s[i] == s[i+1]:
i += 1
i += 1
if s[i] > s[i-1] and pre > s[i-1]: # it is a valley
count += 1
elif s[i] < s[i-1] and pre < s[i-1]: # it is a hill
count += 1
pre = s[i-1]
return count
有人可以帮助我提高O(N)的复杂性。或者告诉我另一种方法,以更好的复杂性做到这一点?请给我看一些例子。提前致谢。
答案 0 :(得分:4)
这是我将如何做到的:
d
(从结果中删除0
)d
在代码中:
def hill_and_vally(s):
d=[x1-x0 for x0,x1 in zip(s,s[1:]) if x1!=x0]
return 2+sum(d0*d1<0 for d0,d1 in zip(d,d[1:]))
当然可以使用for
循环和索引来实现,但zip
和列表推导更加pythonic。
zip(s,s[1:])
是在列表中获取相邻元素对的常用方法。
试验:
>>> hill_and_vally([1,0,0,0,1])
3
>>> hill_and_vally([0,1,0,1,0])
5
>>> hill_and_vally([0,2,2,1,1,0,0])
3
答案 1 :(得分:0)
我知道这个问题已经很老了并且已经回答了,但是最近一次线性扫描就解决了这个问题:
HEX(CAST(HASH(BLOB('1'),0) as VARBINARY(128)))
它对所有输入都适用:
def solution(arr):
prev = None
curr = None
total = 0
for n in arr:
if curr == None:
curr = n
else:
if n != curr:
if prev != None:
if (prev < curr and n < curr) or (prev > curr and n > curr):
total += 1
else:
prev = curr
total += 1
prev = curr
curr = n
if prev != curr:
total += 1
return total
它的作用是,它会跟踪先前的下坡/上坡,如果遇到其他适当的下坡/上坡,则会递增print(solution([1])) # 1
print(solution([1,2])) # 2
print(solution([1,1,1])) # 1
print(solution([1,2,1])) # 3
print(solution([1,2,6])) # 2
print(solution([1,2,3,4,4,3,4,4,5,6])) # 4
print(solution([-10,2,2,2,2])) # 2
print(solution([1,0,0,0,1])) # 3
print(solution([0,1,0,1,0])) # 5
print(solution([0,2,2,1,1,0,0])) # 3
计数器。