Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/algorithm/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 求给定大小的每个相邻子阵的最大值_Python_Algorithm_Data Structures_Queue - Fatal编程技术网

Python 求给定大小的每个相邻子阵的最大值

Python 求给定大小的每个相邻子阵的最大值,python,algorithm,data-structures,queue,Python,Algorithm,Data Structures,Queue,我试图用Python解决以下问题 给定一个数组和一个整数k,求每个大小为k的连续子数组的最大值 这个想法是使用一个双端队列。这是我的代码: def diff_sliding_window(arr, win): # max = -inf Q = [] win_maxes = [] # max of each window for i in range(win): print(Q) while len(Q) > 0 and arr

我试图用Python解决以下问题

给定一个数组和一个整数k,求每个大小为k的连续子数组的最大值

这个想法是使用一个双端队列。这是我的代码:

def diff_sliding_window(arr, win):
#     max = -inf
    Q = []
    win_maxes = [] # max of each window
    for i in range(win):
        print(Q)
        while len(Q) > 0 and arr[i] >= arr[len(Q) - 1]:
            # get rid of the index of the smaller element
            Q.pop() # removes last element
        Q.append(i)
#     print('>>', Q)

    for i in range(win, len(arr)):
#         win_maxes.append(arr[Q[0]])
        print(arr[Q[0]])
        while len(Q) > 0 and Q[0] <= i - win:
            Q.pop()
        while len(Q) > 0 and arr[i] >= arr[len(Q)-1]:
            Q.pop(0)
        Q.append(i)
#     win_maxes.append(arr[Q[0]])

    print(arr[Q[0]])
我没有得到正确的结果


更新

我已经做了马特·蒂默曼斯建议的更改,但仍然没有得到正确的输出。对于
t2
,以及
win=3

78
90
90
89 <--- should be 90
89
78
90
90
89 0和arr[i]>=arr[Q[len(Q)-1]:
#去掉较小元素的索引
Q.pop()#删除最后一个元素
Q.1(i)
#打印(“>>”,Q)
对于范围内的i(赢,蓝(arr)):
#win_maxes.append(arr[Q[0]]
打印(arr[Q[0]])
而len(Q)>0和Q[0]0以及arr[i]>=arr[Q[len(Q)-1]:
Q.popleft()
Q.1(i)
打印(arr[Q[0]])
这种方法(只需对数据进行一次传递)怎么样:

代码 输出 这种方法(只需要对数据进行一次传递)怎么样

代码 输出
下面是一个使用
itertools
tee
的简单解决方案:

def nwise(iterable, n):
    ''' Step through the iterable in groups of n '''
    ts = it.tee(iterable, n)
    for c, t in enumerate(ts):
        next(it.islice(t, c, c), None)
    return zip(*ts)

def max_slide(ns, l):
    return [max(a) for a in nwise(ns, l)]

>>> max_slide([1, 3, -1, -3, 5, 3, 6, 7], 3)
[3, 3, 5, 5, 6, 7]
>>> max_slide([12, 1, 78, 90, 57, 89, 56], 3)
[78, 90, 90, 90, 89]

下面是一个使用
itertools
tee
的简单解决方案:

def nwise(iterable, n):
    ''' Step through the iterable in groups of n '''
    ts = it.tee(iterable, n)
    for c, t in enumerate(ts):
        next(it.islice(t, c, c), None)
    return zip(*ts)

def max_slide(ns, l):
    return [max(a) for a in nwise(ns, l)]

>>> max_slide([1, 3, -1, -3, 5, 3, 6, 7], 3)
[3, 3, 5, 5, 6, 7]
>>> max_slide([12, 1, 78, 90, 57, 89, 56], 3)
[78, 90, 90, 90, 89]

看起来您正在尝试为这个问题实现O(n)算法,这比现在这里的其他两个答案要好

但是,您的实现是不正确的。当你说
arr[i]>=arr[len(Q)-1]
时,你应该说
arr[i]>=arr[Q[len(Q)-1]
arr[i]>=arr[Q[-1]
。您还交换了第二个循环中的
pop
pop(0)
案例。在你修好这些之后,它看起来是正确的

不过,您的算法不是O(n),因为您使用的是
Q.pop(0)
,这需要O(k)时间。因此,您的总运行时间为O(kn)。对
Q
使用deque将解决此问题

在这里,它是完全固定的,带有一些注释来说明它是如何工作的:

from collections import deque

def diff_sliding_window(arr, win):

    if win > len(arr):
        return []

    win_maxes = [] # max of each window

    #Q contains indexes of items in the window that are greater than
    #all items to the right of them.  This always includes the last item
    #in the window
    Q = deque()

    #fill Q for initial window
    for i in range(win):
        #remove anything that isn't greater than the new item
        while len(Q) > 0 and arr[i] >= arr[Q[-1]]:
            Q.pop()
        Q.append(i)

    win_maxes.append(arr[Q[0]])

    for i in range(win, len(arr)):
        #remove indexes (at most 1, really) left of window
        while len(Q) > 0 and Q[0] <= (i-win):
            Q.popleft()

        #remove anything that isn't greater than the new item
        while len(Q) > 0 and arr[i] >= arr[Q[-1]]:
            Q.pop()
        Q.append(i)
        win_maxes.append(arr[Q[0]])

    return win_maxes
从集合导入数据
def差异滑动窗口(arr,win):
如果win>len(arr):
返回[]
win_maxes=[]每个窗口的最大值
#Q包含窗口中大于的项的索引
#所有项目都位于它们的右侧。这始终包括最后一项
#在窗户里
Q=deque()
#为初始窗口填充Q
对于范围内的i(赢):
#删除任何不大于新项目的内容
而len(Q)>0和arr[i]>=arr[Q[-1]]:
Q.pop()
Q.1(i)
win_maxes.append(arr[Q[0]]
对于范围内的i(赢,蓝(arr)):
#删除窗口左侧的索引(最多1个)

当len(Q)>0和Q[0]时,看起来您正在尝试为这个问题实现O(n)算法,这将比这里的其他两个答案更好

但是,您的实现是不正确的。当你说
arr[i]>=arr[len(Q)-1]
时,你应该说
arr[i]>=arr[Q[len(Q)-1]
arr[i]>=arr[Q[-1]
。您还交换了第二个循环中的
pop
pop(0)
案例。在你修好这些之后,它看起来是正确的

不过,您的算法不是O(n),因为您使用的是
Q.pop(0)
,这需要O(k)时间。因此,您的总运行时间为O(kn)。对
Q
使用deque将解决此问题

在这里,它是完全固定的,带有一些注释来说明它是如何工作的:

from collections import deque

def diff_sliding_window(arr, win):

    if win > len(arr):
        return []

    win_maxes = [] # max of each window

    #Q contains indexes of items in the window that are greater than
    #all items to the right of them.  This always includes the last item
    #in the window
    Q = deque()

    #fill Q for initial window
    for i in range(win):
        #remove anything that isn't greater than the new item
        while len(Q) > 0 and arr[i] >= arr[Q[-1]]:
            Q.pop()
        Q.append(i)

    win_maxes.append(arr[Q[0]])

    for i in range(win, len(arr)):
        #remove indexes (at most 1, really) left of window
        while len(Q) > 0 and Q[0] <= (i-win):
            Q.popleft()

        #remove anything that isn't greater than the new item
        while len(Q) > 0 and arr[i] >= arr[Q[-1]]:
            Q.pop()
        Q.append(i)
        win_maxes.append(arr[Q[0]])

    return win_maxes
从集合导入数据
def差异滑动窗口(arr,win):
如果win>len(arr):
返回[]
win_maxes=[]每个窗口的最大值
#Q包含窗口中大于的项的索引
#所有项目都位于它们的右侧。这始终包括最后一项
#在窗户里
Q=deque()
#为初始窗口填充Q
对于范围内的i(赢):
#删除任何不大于新项目的内容
而len(Q)>0和arr[i]>=arr[Q[-1]]:
Q.pop()
Q.1(i)
win_maxes.append(arr[Q[0]]
对于范围内的i(赢,蓝(arr)):
#删除窗口左侧的索引(最多1个)

而len(Q)>0和Q[0]是在引用我的解决方案时添加的“一次通过”注释吗
itertools.tee
可能需要辅助存储(滑动窗口很少),但效率很高。计时使它快了30%-50%。@AChampion我当然希望是这样,因为我没有使用正确的数据结构(=在
result
中使用数组的代码非常未优化,尤其是
k_max
)。别误会,我喜欢函数式编程和itertools。但有时其他的东西更容易掌握。尽管如此:很好的代码<代码>集合。deque
确实稍微改善了一些事情。谢谢,你建立了一套iter/功能性UTIL,所以
nwise
刚刚从架子上取下来,只是
itertools
配方的
pairwise
的一个扩展。@AChampion我没有动力优化它。但是关于collections.deque的评论非常棒(因为它专门用于我的代码所需的两个操作)!谢谢。是否在我的解决方案中添加了“一次通过”评论
itertools.tee
可能需要辅助存储(滑动窗口很少),但效率很高。计时使它快了30%-50%。@AChampion我当然希望是这样,因为我没有使用正确的数据结构(=在
result
中使用数组的代码非常未优化,尤其是
k_max
)。别误会,我喜欢函数式编程和itertools。但有时其他的东西更容易掌握。尽管如此:很好的代码<代码>集合。deque
确实稍微改善了一些事情。谢谢,您建立了一套iter/功能UTIL,因此
nwise
刚刚从架子上取下,并且只是
itertools的
pairwise
的扩展<
def nwise(iterable, n):
    ''' Step through the iterable in groups of n '''
    ts = it.tee(iterable, n)
    for c, t in enumerate(ts):
        next(it.islice(t, c, c), None)
    return zip(*ts)

def max_slide(ns, l):
    return [max(a) for a in nwise(ns, l)]

>>> max_slide([1, 3, -1, -3, 5, 3, 6, 7], 3)
[3, 3, 5, 5, 6, 7]
>>> max_slide([12, 1, 78, 90, 57, 89, 56], 3)
[78, 90, 90, 90, 89]
from collections import deque

def diff_sliding_window(arr, win):

    if win > len(arr):
        return []

    win_maxes = [] # max of each window

    #Q contains indexes of items in the window that are greater than
    #all items to the right of them.  This always includes the last item
    #in the window
    Q = deque()

    #fill Q for initial window
    for i in range(win):
        #remove anything that isn't greater than the new item
        while len(Q) > 0 and arr[i] >= arr[Q[-1]]:
            Q.pop()
        Q.append(i)

    win_maxes.append(arr[Q[0]])

    for i in range(win, len(arr)):
        #remove indexes (at most 1, really) left of window
        while len(Q) > 0 and Q[0] <= (i-win):
            Q.popleft()

        #remove anything that isn't greater than the new item
        while len(Q) > 0 and arr[i] >= arr[Q[-1]]:
            Q.pop()
        Q.append(i)
        win_maxes.append(arr[Q[0]])

    return win_maxes