给定数组A和数K,创建数组B,其中B [i] = min(A [i],A [i + 1] .. A [i + K-1])

大卫

给定一个整数数组A和一个整数值K,创建array B,其中B[i]是子数组的最小值A[i], A[i+1], ..., A[i+K-1]请注意,B.length它将等于A.length - K

例如K = 3A=[1,2,3,4,0,1,2]解决方案是B=[1,2,0,0,0]

A  =  [1,2,3,4,0,1,2]
       _____| | | | |      
B[1] = 1      | | | | 
         _____| | | | 
B[2] =   2      | | | 
           _____| | | 
B[3] =         0  | | 
             _____| | 
B[4] =         0    | 
               _____| 
B[5] =         0

O(kn)时间复杂度的解决方案如下:

public static int[] createArray(int[] arr, int k) {
    int[] result = new int[arr.length];
    for (int i = 0; i <= arr.length - k; i++) {
        int curSmallestVal = arr[i];
        for (int j = i + 1; j < i + k; j++) {
            curSmallestVal = Math.min(curSmallestVal, arr[j]);
        }
        result[i] = curSmallestVal;
    }

    return result;
}

可以使用O(n)运行时提供更优雅的解决方案吗?(可能使用队列)

使用O(n)解决方案进行更新:

public static int[] getMinSlidingWindow(int[] arr, int k) {
    int[] result = new int[arr.length-k+1];
    Deque<Integer> queue = new LinkedList<Integer>();
    //initialize sliding window
    for (int i = 0; i < k; i++) {
        if (!queue.isEmpty() && arr[queue.getLast()] >= arr[i])
            queue.removeLast();
        queue.addLast(i);
    }

    for (int i = k; i < arr.length; i++) {
        result[i-k] = arr[queue.getFirst()];
        while (!queue.isEmpty() && arr[queue.getLast()] >= arr[i])
            queue.removeLast();
        queue.addLast(i);
        while (!queue.isEmpty() && queue.getFirst() <= i-k)
            queue.removeFirst();
    }

    result[arr.length-k] = arr[queue.removeFirst()]; 

    return result;
}
热切的俄语

使用双端队列(该队列支持从正面和背面添加推入和弹出),可以使用一些额外的逻辑来构造运行O(n)的解决方案。

这是解决方案的伪代码。

void getMaxSlidingWindow(int[] A, int k) {
    int[] B = new int[A.length - k];
    // Store the indexes of A in Q
    // Q.front(): index of smallest element in the window, Q.back(): index of the largest one in the window
    DobuleEndedQueue<int> Q = new DobuleEndedQueue<int>(); 

    for(int i=0; i<k; i++) {
       // Fill up the double ended queue for the first k elements
       // Remove elements that we would ignore because they're bigger than the next one in the window
       while(!Q.empty() && A[i] <= A[Q.back()]) {
          Q.popBack();
       }
       Q.pushBack(i);
    }

     for(int i=k; i < A.length; i++) {
       B[i - k] = A[Q.front()]; // The first element in the queue is the index of the smallest element in the window
       // Add the current element to the queue. Before we do, remove all elements that we would ignore immediately because they're bigger than the current one
       while(!Q.empty() && A[i] <= A[Q.back()]  ) {
          Q.popBack();
       }
       Q.pushToBack(i);
       // Remove any index from the front of the queue which is no longer in the window
       while(!Q.empty() && Q.front() <= i-k) {
         Q.popFront();
       }
    }
    B[A.length - k] = A[Q.front()];
}

解决方案的时间复杂度为O(n):我们对所有元素进行一次迭代,然后一次将其添加或删除到双端队列中。完成的最大运算为2n,这是O(n)复杂度。

为了使该解决方案起作用,您需要使用以下操作来实现双头队列数据结构:

class DobuleEndedQueue
int front(), void pushFront(int n), void popFront() // peeks at the front element, adds and removes to the front
int back(), void pushBack(int n) , void popBack() // same for the back element

通过一个简单的示例进一步说明该算法:

  • 循环访问前k个元素,并将它们作为索引插入到双端Q数据结构中,以便A [Q.front()]是窗口中的最小元素,而A [Q.back()]是窗口中的最大元素。
  • 当我们建立窗口时,请从此队列中丢弃“不必要的”元素:既不会计数的最小元素,也包括在窗口之外的元素
  • 建立A = [8、6、9、2]和k-3的队列的示例
    1. Q = [0],(将0插入Q的后面,因为A [0]是我们看到的最小元素。)
    1. Q = [1],(A [1] <Q.back()因此弹出back元素并替换为1。之所以这样做,是因为从现在开始寻找最小的数字时A [0]将是无关紧要的。)
    1. Q = [1,2],B = [8](A [2]> Q.back(),因此我们在Q上加上2。B [0]将是Q中最小的项,即A [Q.first()],即A [1])
    1. Q = [3],B = [8,2](A [4]小于Q中的所有元素,因此我们将其全部弹出。B[1]将是Q中最小的元素,A [Q.first ()],即A [3]

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

给定数组A和数K,创建数组B,其中B [i] = min(A [i],A [i + 1] .. A [i + K-1])

来自分类Dev

MATLAB:给定A和B,其中size(B,1)<size(A,1)返回I,使得A(I,:) = B

来自分类Dev

在C中,{a [i] = a [++ i]}等于{a [i] = a [i + 1]; i ++;}?

来自分类Dev

性能最高的方法,用于计算lcm(i,j),i和j的和,范围从1到k

来自分类Dev

递增++ i,i ++和i + = 1

来自分类Dev

计算数组中 a[i] < a[j] > a[k] 的数量的有效算法,其中 i < j < k

来自分类Dev

Java-a [i] = a [i-1]中的数组访问次数;

来自分类Dev

如何在Numpy / Theano中表达c [i,j,k] = a [i,j] * b [i,k]?

来自分类Dev

为什么我的模式未涵盖`std :: i64 :: MIN .. =-1i64`和`1i64 .. = std :: i64 :: MAX`?

来自分类Dev

计算lcm(i,j),i和j之和的范围是1到k的最有效方法是什么?

来自分类Dev

是否有关于结果[i] + = A [k] * sin(B [k] * C [i] + D [k])的内在指令?

来自分类Dev

在C ++中,最好i> -1或i> = 0

来自分类Dev

是a ^ i ^ 2 | i> = 1常规吗?

来自分类Dev

为什么要使用 i = (i +1) & mask 递增,其中 mask 是 0b1111?

来自分类Dev

给定两个未排序的数组,找到对数,其中A [i]> X和B [i]> Y

来自分类Dev

i ++和i = i + 1之间的原子性差异

来自分类Dev

i = i + 1和++ i之间的速度比较

来自分类Dev

该代码的含义:for(i = 0; argv [1] [i]!='\ 0'; i ++)

来自分类Dev

与 i++ 和 i=i+1 混淆

来自分类Dev

i == j == k的意外结果?

来自分类Dev

数学-公式V [i] =([V [i-1] * V [i-1] /(i + 2)] + V [i-1] * i + i + 1)%666013

来自分类Dev

说明可选的PHP For循环语法:for($ i = 1,$ j = 0; $ i <= 10; $ j + = $ i,print $ i,$ i ++);

来自分类Dev

C:对于(i = 0; i <= N; i ++){t [i] = pow(a,0.i); }总是返回1

来自分类Dev

为什么“ i&(i ^(i-1))”等效于“ i&(-i)”

来自分类Dev

在 python 的 for 循环中使用 Ax=b 中的先前值 x(i-1) 来获取 x(i) 数组

来自分类Dev

(i +1)<ii和(i +1)> ii怎么都成立?

来自分类Dev

使用R将变量名称“ QW1I5K20”的值存储在数组元素Q [1,5,20]中

来自分类Dev

sum(1 / prime [i] ^ 2)> = 1?

来自分类Dev

C ++语法,i%k == l%k == 0和i%k == 0 && l%k == 0之间的差

Related 相关文章

  1. 1

    给定数组A和数K,创建数组B,其中B [i] = min(A [i],A [i + 1] .. A [i + K-1])

  2. 2

    MATLAB:给定A和B,其中size(B,1)<size(A,1)返回I,使得A(I,:) = B

  3. 3

    在C中,{a [i] = a [++ i]}等于{a [i] = a [i + 1]; i ++;}?

  4. 4

    性能最高的方法,用于计算lcm(i,j),i和j的和,范围从1到k

  5. 5

    递增++ i,i ++和i + = 1

  6. 6

    计算数组中 a[i] < a[j] > a[k] 的数量的有效算法,其中 i < j < k

  7. 7

    Java-a [i] = a [i-1]中的数组访问次数;

  8. 8

    如何在Numpy / Theano中表达c [i,j,k] = a [i,j] * b [i,k]?

  9. 9

    为什么我的模式未涵盖`std :: i64 :: MIN .. =-1i64`和`1i64 .. = std :: i64 :: MAX`?

  10. 10

    计算lcm(i,j),i和j之和的范围是1到k的最有效方法是什么?

  11. 11

    是否有关于结果[i] + = A [k] * sin(B [k] * C [i] + D [k])的内在指令?

  12. 12

    在C ++中,最好i> -1或i> = 0

  13. 13

    是a ^ i ^ 2 | i> = 1常规吗?

  14. 14

    为什么要使用 i = (i +1) & mask 递增,其中 mask 是 0b1111?

  15. 15

    给定两个未排序的数组,找到对数,其中A [i]> X和B [i]> Y

  16. 16

    i ++和i = i + 1之间的原子性差异

  17. 17

    i = i + 1和++ i之间的速度比较

  18. 18

    该代码的含义:for(i = 0; argv [1] [i]!='\ 0'; i ++)

  19. 19

    与 i++ 和 i=i+1 混淆

  20. 20

    i == j == k的意外结果?

  21. 21

    数学-公式V [i] =([V [i-1] * V [i-1] /(i + 2)] + V [i-1] * i + i + 1)%666013

  22. 22

    说明可选的PHP For循环语法:for($ i = 1,$ j = 0; $ i <= 10; $ j + = $ i,print $ i,$ i ++);

  23. 23

    C:对于(i = 0; i <= N; i ++){t [i] = pow(a,0.i); }总是返回1

  24. 24

    为什么“ i&(i ^(i-1))”等效于“ i&(-i)”

  25. 25

    在 python 的 for 循环中使用 Ax=b 中的先前值 x(i-1) 来获取 x(i) 数组

  26. 26

    (i +1)<ii和(i +1)> ii怎么都成立?

  27. 27

    使用R将变量名称“ QW1I5K20”的值存储在数组元素Q [1,5,20]中

  28. 28

    sum(1 / prime [i] ^ 2)> = 1?

  29. 29

    C ++语法,i%k == l%k == 0和i%k == 0 && l%k == 0之间的差

热门标签

归档