【问题标题】:What is the time complexity of this function?这个函数的时间复杂度是多少?
【发布时间】:2017-09-11 07:59:06
【问题描述】:

以下是 Java 中Sliding Window Maximum 问题的示例解决方案。

给定一个数组 nums,有一个大小为 k 的滑动窗口,它是 从数组的最左边移动到最右边。你只能 查看窗口中的 k 个数字。每次滑动窗口移动 就在一个位置。

我想得到这个函数的时间和空间复杂度。以下是我认为的答案:

时间:O((n-k)(k * logk)) == O(nklogk)

空格(辅助):O(n) 用于返回 int[]O(k) 用于 pq。总计O(n)

这对吗?

private static int[] maxSlidingWindow(int[] a, int k) {
    if(a == null || a.length == 0) return new int[] {};
    PriorityQueue<Integer> pq = new PriorityQueue<Integer>(k, new Comparator<Integer>() {
        // max heap
        public int compare(Integer o1, Integer o2) {
            return o2 - o1;
        }
    });
    int[] result = new int[a.length - k + 1];
    int count = 0;
    // time: n - k times
    for (int i = 0; i < a.length - k + 1; i++) {
        for (int j = i; j < i + k; j++) {
            // time k*logk (the part I'm not sure about)
            pq.offer(a[j]);
        }

        // logk
        result[count] = pq.poll();
        count = count + 1;
        pq.clear();
    }
    return result;
}

【问题讨论】:

  • k 真的是一个常数吗?
  • 如果 k 不是常数,你如何从方程 O((n-k)(k * logk)) 中消除它?

标签: time-complexity big-o


【解决方案1】:

除了 -

for (int j = i; j < i + k; j++) {
     // time k*logk (the part I'm not sure about)
     pq.offer(a[j]);
}

这里的执行总数是log1 + log2 + log3 + log4 + ... + logk。这个系列的总结——

log1 + log2 + log3 + log4 + ... + logk = log(k!)

第二个想法是,您可以使用双端队列属性(O(n))比线性时间解决方案做得更好。这是我的解决方案 -

public int[] maxSlidingWindow(int[] nums, int k) {      
    if (nums == null || k <= 0) {
        return new int[0];
    }
    int n = nums.length;
    int[] result = new int[n - k + 1];
    int indx = 0;

    Deque<Integer> q = new ArrayDeque<>();

    for (int i = 0; i < n; i++) {

        // remove numbers out of range k
        while (!q.isEmpty() && q.peek() < i - k + 1) {
            q.poll();
        }

        // remove smaller numbers in k range as they are useless
        while (!q.isEmpty() && nums[q.peekLast()] < nums[i]) {
            q.pollLast();
        }

        q.offer(i);
        if (i >= k - 1) {
            result[indx++] = nums[q.peek()];
        }
    }

    return result;
}

HTH。

【讨论】:

    猜你喜欢
    • 2020-12-03
    • 2011-08-07
    • 1970-01-01
    • 2015-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多