Python 在列表中查找所有山丘和山谷

Python 在列表中查找所有山丘和山谷,python,algorithm,Python,Algorithm,我正在编写一个函数来查找给定列表中的所有山丘和山谷。例如,[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 whi

我正在编写一个函数来查找给定列表中的所有山丘和山谷。例如,[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
def hill_和vally(s):
如果不是s或len(s)<2:
返回0
i=0
计数=0
pre=无
而我=0:
计数+=1
打破
其他:
而s[i]==s[i+1]:
i+=1
i+=1
如果s[i]>s[i-1]和pre>s[i-1]:#这是一个山谷
计数+=1
埃利夫s[i]

有人能帮我把复杂度提高到O(N)吗。或者告诉我另一种更复杂的方法?请给我举几个例子。提前谢谢

我会这样做:

  • 计算连续元素之间的差异
    d
    (从结果中删除
    0
    s)
  • 计算
    d
  • 返回2加上该计数(因为即使在单调递增的序列中也有一个山和一个谷)
代码:

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:]))

处理角落案例,如报告的
[1,1,1,1]
留作练习:-)

以下是我的做法:

  • 计算连续元素之间的差异
    d
    (从结果中删除
    0
    s)
  • 计算
    d
  • 返回2加上该计数(因为即使在单调递增的序列中也有一个山和一个谷)
代码:

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:]))

处理角落案例,如报告的
[1,1,1,1]
留作练习:-)

我知道这个问题已经很老了,而且已经得到了回答,但最近仅通过一次线性扫描就解决了同样的问题:

def溶液(arr):
prev=无
当前=无
总数=0
对于arr中的n:
如果curr==无:
curr=n
其他:
如果n!=货币:
如果上一个!=无:
如果(上一次<当前值,n次<当前值)或(上一次>当前值,n次>当前值):
总数+=1
其他:
上一次=当前
总数+=1
上一次=当前
curr=n
如果上一个!=货币:
总数+=1
返回总数
它适用于所有输入:

打印(解决方案([1])#1
打印(解决方案([1,2])#2
打印(解决方案([1,1,1])#1
打印(解决方案([1,2,1])#3
打印(解决方案([1,2,6])#2
打印(解决方案([1,2,3,4,4,3,4,4,5,6])#4
打印(溶液([-10,2,2,2,2])#2
打印(解决方案([1,0,0,1])#3
打印(溶液([0,1,0,1,0])#5
打印(解决方案([0,2,2,1,1,0,0])#3

它所做的是,它跟踪以前的下坡/上坡,并在遇到另一个适当的下坡/上坡时增加计数器。

我知道这个问题已经很老了,并且已经得到了回答,但最近仅通过一次线性扫描就解决了同样的问题:

def溶液(arr):
prev=无
当前=无
总数=0
对于arr中的n:
如果curr==无:
curr=n
其他:
如果n!=货币:
如果上一个!=无:
如果(上一次<当前值,n次<当前值)或(上一次>当前值,n次>当前值):
总数+=1
其他:
上一次=当前
总数+=1
上一次=当前
curr=n
如果上一个!=货币:
总数+=1
返回总数
它适用于所有输入:

打印(解决方案([1])#1
打印(解决方案([1,2])#2
打印(解决方案([1,1,1])#1
打印(解决方案([1,2,1])#3
打印(解决方案([1,2,6])#2
打印(解决方案([1,2,3,4,4,3,4,4,5,6])#4
打印(溶液([-10,2,2,2,2])#2
打印(解决方案([1,0,0,1])#3
打印(溶液([0,1,0,1,0])#5
打印(解决方案([0,2,2,1,1,0,0])#3

它所做的是,它跟踪以前的下坡/上坡,并在满足另一个适当的下坡/上坡条件时增加
total
计数器。

这3是怎么回事<代码>[0,2,2,1,1,0,0]
这不是
(0)(2,2)(1,1)(0,0)
4
?@SamerTufail
1
既不是局部极小值,也不是局部极大值。0:valley 22:hill 00:valley 11既不是山也不是山valley@12345:我建议你通过编辑问题来添加解释。没有这一点,整个问题就不可能被理解。这是怎么回事<代码>[0,2,2,1,1,0,0]这不是
(0)(2,2)(1,1)(0,0)
4
?@SamerTufail
1
既不是局部极小值,也不是局部极大值。0:valley 22:hill 00:valley 11既不是山也不是山valley@12345:我建议你通过编辑问题来添加解释。没有这一点,就无法理解整个问题。伟大的解决方案!谢谢。它在所有相同的输入(如
[1,1,1,1]
和输出
2
而不是
1
时都失败了。很好的解决方案!谢谢。它在所有相同的输入(如
[1,1,1,1]
和输出
2
而不是
1
时都失败了。感谢您提供了出色的算法。我可以和你联系讨论一下吗?谢谢你的精彩算法。我可以和你联系讨论一下吗。