From 0f0215a9e212a89cc8898f4dd24a43ee1cce15d4 Mon Sep 17 00:00:00 2001 From: Wei Jiang Date: Sun, 15 Oct 2023 13:49:30 +0200 Subject: [PATCH 1/4] add monotonic queue algorithm --- data_structures/queue/monotonic_queue.py | 39 ++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 data_structures/queue/monotonic_queue.py diff --git a/data_structures/queue/monotonic_queue.py b/data_structures/queue/monotonic_queue.py new file mode 100644 index 000000000000..78de2cfe2b3e --- /dev/null +++ b/data_structures/queue/monotonic_queue.py @@ -0,0 +1,39 @@ +from __future__ import annotations + +from double_ended_queue import Deque + +arr = [1, 3, -1, -3, 5, 3, 6, 7] +k = 3 +expect = [3, 3, 5, 5, 6, 7] + + +def max_sliding_window(arr: list[float], k: int) -> list[float]: + """ + Given an array of integers nums, there is a sliding window of size k which is moving + from the very left of the array to the very right. + Each time the sliding window of length k moves right by one position. + Return the max sliding window. + >>> max_sliding_window(arr, k) == expect + True + """ + max_val = [] + queue = Deque() + for i in range(len(arr)): + # pop the element if the index is outside the window size k + if queue and i - queue._front.val >= k: + queue.popleft() + # keep the queue monotonically decreasing + # so that the max value is always in the top + while queue and arr[i] >= arr[queue._back.val]: + queue.pop() + queue.append(i) + # the maximum value is the first element in queue + if i >= k - 1: + max_val.append(arr[queue._front.val]) + return max_val + + +if __name__ == "__main__": + from doctest import testmod + + testmod() From ba4d0302adb4caf4a54dfcde5f56753f6d13a31c Mon Sep 17 00:00:00 2001 From: Wei Jiang Date: Sun, 15 Oct 2023 13:58:06 +0200 Subject: [PATCH 2/4] add monotonic queue algorithm --- data_structures/queue/monotonic_queue.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data_structures/queue/monotonic_queue.py b/data_structures/queue/monotonic_queue.py index 78de2cfe2b3e..3f8539e0c10c 100644 --- a/data_structures/queue/monotonic_queue.py +++ b/data_structures/queue/monotonic_queue.py @@ -23,7 +23,7 @@ def max_sliding_window(arr: list[float], k: int) -> list[float]: if queue and i - queue._front.val >= k: queue.popleft() # keep the queue monotonically decreasing - # so that the max value is always in the top + # so that the max value is always on the top while queue and arr[i] >= arr[queue._back.val]: queue.pop() queue.append(i) From 5163d265509da8f1fedc1d47fab3e8497a73b611 Mon Sep 17 00:00:00 2001 From: Wei Jiang Date: Sun, 15 Oct 2023 14:04:41 +0200 Subject: [PATCH 3/4] add monotonic queue algorithm --- data_structures/queue/monotonic_queue.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/data_structures/queue/monotonic_queue.py b/data_structures/queue/monotonic_queue.py index 3f8539e0c10c..79a207366282 100644 --- a/data_structures/queue/monotonic_queue.py +++ b/data_structures/queue/monotonic_queue.py @@ -1,26 +1,26 @@ from __future__ import annotations -from double_ended_queue import Deque +from .double_ended_queue import Deque arr = [1, 3, -1, -3, 5, 3, 6, 7] -k = 3 +window_size = 3 expect = [3, 3, 5, 5, 6, 7] -def max_sliding_window(arr: list[float], k: int) -> list[float]: +def max_sliding_window(arr: list[float], window_size: int) -> list[float]: """ Given an array of integers nums, there is a sliding window of size k which is moving from the very left of the array to the very right. - Each time the sliding window of length k moves right by one position. + Each time the sliding window of length window_size moves right by one position. Return the max sliding window. - >>> max_sliding_window(arr, k) == expect + >>> max_sliding_window(arr, window_size) == expect True """ max_val = [] queue = Deque() for i in range(len(arr)): # pop the element if the index is outside the window size k - if queue and i - queue._front.val >= k: + if queue and i - queue._front.val >= window_size: queue.popleft() # keep the queue monotonically decreasing # so that the max value is always on the top @@ -28,7 +28,7 @@ def max_sliding_window(arr: list[float], k: int) -> list[float]: queue.pop() queue.append(i) # the maximum value is the first element in queue - if i >= k - 1: + if i >= window_size - 1: max_val.append(arr[queue._front.val]) return max_val From 5a76198e85e145120064baa560f5ccfa8fef341e Mon Sep 17 00:00:00 2001 From: Wei Jiang Date: Mon, 16 Oct 2023 00:31:59 +0200 Subject: [PATCH 4/4] monotonic queue --- data_structures/queue/monotonic_queue.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/data_structures/queue/monotonic_queue.py b/data_structures/queue/monotonic_queue.py index 79a207366282..b19672fd7e66 100644 --- a/data_structures/queue/monotonic_queue.py +++ b/data_structures/queue/monotonic_queue.py @@ -1,6 +1,6 @@ from __future__ import annotations -from .double_ended_queue import Deque +from collections import deque arr = [1, 3, -1, -3, 5, 3, 6, 7] window_size = 3 @@ -17,19 +17,19 @@ def max_sliding_window(arr: list[float], window_size: int) -> list[float]: True """ max_val = [] - queue = Deque() + mono_queue: deque = deque() for i in range(len(arr)): # pop the element if the index is outside the window size k - if queue and i - queue._front.val >= window_size: - queue.popleft() + if mono_queue and i - mono_queue[0] >= window_size: + mono_queue.popleft() # keep the queue monotonically decreasing # so that the max value is always on the top - while queue and arr[i] >= arr[queue._back.val]: - queue.pop() - queue.append(i) + while mono_queue and arr[i] >= arr[mono_queue[-1]]: + mono_queue.pop() + mono_queue.append(i) # the maximum value is the first element in queue if i >= window_size - 1: - max_val.append(arr[queue._front.val]) + max_val.append(arr[mono_queue[0]]) return max_val