[英]Compare each element in a list with all the previous consecutive elements
我想将列表 a 的每个元素与其之前的连续元素进行比较。 i 在前向的每次迭代需要对 j 在后向的迭代次数(或简单地从 i 的当前索引反向迭代 j)并比较之前的连续元素是否满足条件 a[i] >= a[j] . 如果条件为真,则将计数加 1 (count++) 如果条件失败(即 a[i] < a[j] 在任何索引处)将计数附加到新列表 li[] 并打印 li。
我尝试了以下方法但失败了:
a = [1,2,3,2,4,6,1,2]
li=[]
count = 0
for i in range(len(a)):
for j in range(i,0,-1):
while a[i] >= a[j]:
count+=1
li.append(count)
print(li)
输出应如下所示:
1 2 3 1 5 6 1 2
有没有什么具体的方法可以解决这个复杂度为 O(n) 的问题。 就像有什么算法可以解决在某种方法中需要 2 个或更多嵌套循环的问题,以优化时间复杂度。
这是来自需要堆栈在线性时间内解决的前瞻或后视问题类别:
def smaller_preceding(a):
stack = []
result = []
for i, x in enumerate(a):
while stack and a[stack[-1]] < x:
stack.pop()
# current index minus index of last bigger element!
result.append(i - (stack[-1] if stack else -1))
stack.append(i)
return result
>>> smaller_preceding([1,2,3,2,4,6,1,2])
[1, 2, 3, 1, 5, 6, 1, 2]
堆栈跟踪严格减少元素的索引,例如,在某一时刻它将是:
[2, 3]
# stack contains indeces (0 and 1 have been popped)
对应元素:
[3, 2]
# ... of decreasing elements (... because 1 and 2 were smaller than 3)
其理由是,对于每一个元素x
在a
,你知道你可以完全忘记所有小先前的元素,你将永远不会“闯过” x
上回头看时后(如果有更小的元素比未来元素小,所以将是x
!)。
您可以轻松验证for
循环是否有 n 次迭代。 此外,可以看到while
循环也最多有 n 次迭代(即使它是嵌套的),因为每个索引只能从堆栈中弹出一次。 因此,整个算法在时间和空间上都是线性的。
使用 numpy 您可以评估整个np.array
比较。 这为您节省了一个循环。 第一步创建包含数字大于当前值的所有索引的array([1, 2, 3, 4, 5]
: array([1, 2, 3, 4, 5]
(对于原始列表的索引 6)。
在第二步中,将空数组作为当前索引+1 idx+1
添加到li
,因为这是该点必须返回多远(直到列表开始)。 如果数组非空,则将idx
与最大值(即index
-array 中最右边的索引)之间的index
相加。 同样,这是指针必须移动的距离。
import numpy as np
a = np.array([1, 2, 3, 2, 4, 6, 1, 2])
li = []
for idx, val in enumerate(a):
index = np.where(a[0:idx+1] > val)
if np.size(index) == 0:
li.append(idx+1)
else:
li.append(idx - np.max(index))
print(li)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.