Skip to main content

Command Palette

Search for a command to run...

get_max_window C++ and Rust

Published
•3 min read•View as Markdown

Input:

  1. Array of integers.

  2. An integer 'w' which is the window size.

Output:

  1. An array of integers, representing the maximum values in all contiguous subarrays of size 'w'.

Algorithm

uses a deque to efficiently keep track of the maximum element in the current window of size 'w'. It ensures that the first element in the deque is always the maximum element in the current window, and as the window slides, it updates the deque and the result array accordingly. This approach achieves an overall time complexity of O(n), making it more efficient than a naive approach that would have a time complexity of O(nw), where 'n' is the size of the input array and 'w' is the window size.

C++

// Online C++ compiler to run C++ program online
#include<iostream>
#include<deque>
#include<vector>
#include<cstdlib>

using namespace std;

vector<int> getMaxWindow(vector<int> arr, int w) {
    if (arr.empty() || w < 1 || arr.size() < w) {
        return vector<int>();
    }
    deque<int> qmax;
    vector<int> res(arr.size() - w + 1);
    int index = 0;
    for (int R = 0; R < arr.size(); R++) {
        while (!qmax.empty() && arr[qmax.back()] <= arr[R]) {
            qmax.pop_back();
        }
        qmax.push_back(R);
        if (qmax.front() == R - w) {
            qmax.pop_front();
        }
        if (R >= w - 1) {
            res[index++] = arr[qmax.front()];
        }
    }
    return res;
}

int main() {
    vector<int> arr = {1,2,3,4,5,6,7,8,9};
    int w = 3;
    vector<int> res = getMaxWindow(arr, w);
    for(int i = 0; i < res.size(); i++) {
        cout << res[i] << " ";
    }
    return 0;
}

Rust

use std::collections::VecDeque;

fn get_max_window(arr: &[i32], w: usize) -> Vec<i32> {
    if w < 1 || arr.len() < w {
        return vec![];
    }
    let mut qmax = VecDeque::new();
    let mut res = vec![0; arr.len() - w + 1];
    let mut index = 0;
    for r in 0..arr.len() {
        while !qmax.is_empty() && arr[*qmax.back().unwrap()] <= arr[r] {
            qmax.pop_back();
        }
        qmax.push_back(r);
        if r >= w && qmax.front().unwrap() == &(r - w) {
            qmax.pop_front();
        }
        if r >= w - 1 {
            res[index] = arr[*qmax.front().unwrap()];
            index += 1;
        }
    }
    res
}

fn main() {
    let arr = vec![1, 2, 3, 4, 5, 6, 7, 8, 9];
    let w = 3;
    let res = get_max_window(&arr, w);
    for i in res {
        println!("{}", i);
    }
}

Python

from collections import deque
import random
def getMaxWindow(arr, w):
    if arr is None or w < 1 or len(arr) < w:
        return None
    qmax = deque()
    res = [0] * (len(arr) - w + 1)
    index = 0
    for R in range(len(arr)):
        while qmax and arr[qmax[-1]] <= arr[R]:
            qmax.pop()
        qmax.append(R)
        if qmax[0] == R - w:
            qmax.popleft()
        if R >= w - 1:
            res[index] = arr[qmax[0]]
            index += 1
    return res

def rightWay(arr, w):
    if arr is None or w < 1 or len(arr) < w:
        return None
    res = [0] * (len(arr) - w + 1)
    index = 0
    L = 0
    R = w - 1
    while R < len(arr):
        max_val = max(arr[L:R+1])
        res[index] = max_val
        index += 1
        L += 1
        R += 1
    return res

def generateRandomArray(maxSize, maxValue):
    import random
    arr = [random.randint(0, maxValue) for _ in range(random.randint(1, maxSize + 1))]
    return arr

def isEqual(arr1, arr2):
    if arr1 is None and arr2 is None:
        return True
    if arr1 is None or arr2 is None or len(arr1) != len(arr2):
        return False
    for i in range(len(arr1)):
        if arr1[i] != arr2[i]:
            return False
    return True

def test():
    testTime = 100000
    maxSize = 100
    maxValue = 100
    print("test begin")
    for i in range(testTime):
        arr = generateRandomArray(maxSize, maxValue)
        w = random.randint(0, len(arr))
        ans1 = getMaxWindow(arr, w)
        ans2 = rightWay(arr, w)
        if not isEqual(ans1, ans2):
            print("Oops!")
    print("test finish")

if __name__ == "__main__":
    test()

More from this blog

c_void到u8 - laertes-2023

为什么把c_void重命名为u8? 类型大小: u8通常代表一个单字节(8位)的无符号整数。c_void作为一个“空”类型,通常也被当作一个单字节进行处理(尽管这取决于具体的实现)。因此,这两者在大小上是匹配的。 类型转换简便: u8是一个非常基础的类型,与之进行类型转换通常比较方便。 操作简单: u8类型上可用的操作相对简单,可能更容易进行后续的代码分析或转换。 为什么不把其他东西重命名为u8? 类型语义: 其他类型可能具有其自己的语义和操作,这些可能不适用或不等价于u8。 数据...

Sep 5, 20231 min read

Retriever's blog

48 posts