简体   繁体   English

我怎样才能更有效地编写这个算法? 以降低时间复杂度的方式?

[英]how can i write this algorithm more efficiently ? in a way that reduce time complexity?

So I write this code and I wanted to reduce time complexity of it but am not sure how, so what is the best way to write a more efficient algorithm so I can reduce time complexity, the code subtract from each element the first small number after it for example if the array is [1, 5, 6, 3, 2] then the result is [1, 2, 3, 1, 2] .所以我写了这段代码,我想降低它的时间复杂度,但不知道怎么做,那么写一个更有效的算法的最好方法是什么,这样我就可以降低时间复杂度,代码从每个元素中减去后面的第一个小数字例如,如果数组是[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)

Indeed, your solution has O(n²) time complexity.实际上,您的解决方案具有O(n²)时间复杂度。 You can improve on that.你可以改进它。

Start from the end of the list and walk backwards.从列表的末尾开始并向后走。

While doing so, push an inspected list value on a stack when it is not less than the value currently on the top of the stack.这样做时,当检查的列表值不小于当前堆栈顶部的值时,将其压入堆栈。 At the same time output the difference.同时output的区别。

When, on the other hand, an inspected value is less than the value on the top of the stack, then pop the stack until the value on the input value is no longer less than the value on top of the stack, and do again as described in the previous paragraph.另一方面,当检查的值小于堆栈顶部的值时,则弹出堆栈,直到输入值上的值不再小于堆栈顶部的值,然后再次执行上一段中描述的。

Here is an implementation of that idea:这是该想法的实现:

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

Call this function as follows:调用这个 function 如下:

arr = [1, 5, 6, 3, 2]
print (solve(arr))   # [1, 2, 3, 1, 2]

This algorithm has a linear time time complexity: O(n) .该算法具有线性时间复杂度: O(n) Although the inner while loop looks suspicious of a non-linear time complexity, it still is, because a given list value will at most be pushed and pulled only once on/off the stack.尽管内部的while循环看起来对非线性时间复杂度很怀疑,但它仍然存在,因为给定的列表值最多只能在堆栈上/从堆栈中被推入和拉出一次

Use a stack where each item on the stack is a tuple: (index, value) .使用堆栈,其中堆栈上的每个项目都是一个元组: (index, value) Pop items off the stack when a smaller value is found.当找到较小的值时,将项目从堆栈中弹出。 Then push the new tuple onto the stack.然后将新元组推入堆栈。 In pseudocode:在伪代码中:

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

And in python:在 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM