[英]how can i write this algorithm more efficiently ? in a way that reduce time complexity?
所以我写了这段代码,我想降低它的时间复杂度,但不知道怎么做,那么写一个更有效的算法的最好方法是什么,这样我就可以降低时间复杂度,代码从每个元素中减去后面的第一个小数字例如,如果数组是[1, 5, 6, 3, 2]
那么结果是[1, 2, 3, 1, 2]
。
# an array with numbers
arr = [1, 5, 6, 3, 2]
# outer loop picks all element one by one
for i in range(0, len(arr), 1):
Next = arr[i]
# inner loop looks for the next smaller element
for j in range(i + 1, len(arr), 1):
if arr[i] > arr[j]:
# if the condition is true, the element will be subtracted form the next smaller element
# if there was no next smaller element, the element will kept without change
Next = arr[i] - arr[j]
break
print(Next)
实际上,您的解决方案具有O(n²)时间复杂度。 你可以改进它。
从列表的末尾开始并向后走。
这样做时,当检查的列表值不小于当前堆栈顶部的值时,将其压入堆栈。 同时output的区别。
另一方面,当检查的值小于堆栈顶部的值时,则弹出堆栈,直到输入值上的值不再小于堆栈顶部的值,然后再次执行上一段中描述的。
这是该想法的实现:
def solve(arr):
stack = [0]
result = arr[:]
# outer loop picks all element one by one
for i in range(len(arr) - 1, -1, -1):
val = arr[i]
while val <= stack[-1]:
stack.pop()
result[i] = val - stack[-1]
stack.append(val)
return result
调用这个 function 如下:
arr = [1, 5, 6, 3, 2]
print (solve(arr)) # [1, 2, 3, 1, 2]
该算法具有线性时间复杂度: O(n) 。 尽管内部的while
循环看起来对非线性时间复杂度很怀疑,但它仍然存在,因为给定的列表值最多只能在堆栈上/从堆栈中被推入和拉出一次。
使用堆栈,其中堆栈上的每个项目都是一个元组: (index, value)
。 当找到较小的值时,将项目从堆栈中弹出。 然后将新元组推入堆栈。 在伪代码中:
for each array element
while the stack is not empty
if the top stack_value is greater than the element_value
pop the (index, stack_value) from the stack
set arr[index] = stack_value - element_value
push the tuple (index, element_value) onto the stack
在 python 中:
arr = [1, 5, 6, 3, 2]
stack = []
for i in range(len(arr)):
while len(stack) and stack[-1][1] > arr[i]:
index, value = stack.pop()
arr[index] = value - arr[i]
stack.append((i, arr[i]))
print arr # [1, 2, 3, 1, 2]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.