难题新题 2D MAX POOL,求看是否最优解,是否还可再优化

还是帮朋友做的,朋友看面经,最优解是O(mn)

让你实现一个2D MAX POOL函数。具体来说,给一个nxm的矩阵A,给一个整数k,用kxk的小窗口在矩阵A上滑动,每滑到一个位置,就计算这个kxk小窗口中的所有数字的最大值。滑动所有可能的位置之后,可以得到一个(n-k+1)x(m-k+1)的矩阵B。让你输出这个矩阵。

基本是 sliding window maximum 变形,于是我是先对每个row implement sliding window maximum, 然后在对col 实施 sliding window maximum。
额,想不到优化的了,求大家想法
谢谢!!!

private static int[][] findMax(int[][] array, int k) {
		int[][] row = new int[array.length][array[0].length - k + 1];
		
		for (int i = 0; i < array.length; i++) {
			row[i] = maxK(array[i], k);
		}
		int[][] res = new int[array.length - k + 1][row[0].length];
		for (int i = 0; i < row[0].length; i++) {
			int[] temp = new int[row.length];
			for (int t = 0; t < row.length; t++) {
				temp[t] = row[t][i];
			}
			int[] tempR = maxK(temp, k);
			for (int t = 0; t < tempR.length; t++) {
				res[t][i] = tempR[t];
			}
		}
		return res;
	}
	
	private static int[] maxK(int[] array, int k) {
		if (array == null || k == 1) {
			return array;
		}
		int[] res = new int[array.length - k + 1];
		Deque<Integer> deque = new ArrayDeque();
		
		for (int i = 0; i < array.length; i++) {
			while(!deque.isEmpty() && deque.peek() < i - k + 1) {
				deque.poll();
			}
			
			while (!deque.isEmpty() && array[deque.peekLast()] < array[i]) {
				deque.pollLast();
			}
			deque.offer(i);
			if (i - k + 1 >= 0) {
				res[i - k + 1] = array[deque.peek()];
			}
		}
		return res;
	}

什么公司?

额,我其实也不知道,朋友问我的,
不过他最近在准备 bloomberg 和 tusimple 应该是这两个中的一个吧

狗家考过这题。
matrix的题目的解题套路以前在 2018秋季FLAG押题班第2课- Matrix专题 总结过了,无非就两种。
第一种是2D变1D。
第二种参考下面用一个额外辅助的matrix :

谢谢!! x老师
因为要找k * k小窗口中的所有数字的最大值, 1D 是没法实现的

辅助matrix的话,因为 k*k 的max
int test = new int{{100, 27, 35, 40, 49, 55, 59},
{17, 35, 39, 40, 55, 58, 60},
{13, 27, 35, 40, 49, 55, 59},
{17, 35, 39, 40, 55, 58, 60}};

我能理解您这个图,运用到sum,因为他们是包括在内的 可以减。
但是 如果运用到max的话,边 sliding 她的max 是变化的
我这个例子 sub matrix[0 – 2][0 ----2] max 是100
但是 sub matrix[1 – 2][1 ----2] max 而是39.
抱歉我没能明白您这第二个辅助 怎么能运用到这里 找max
可能我想的太浅了
谢谢!!

max的话应该用第一种,回头我写个伪代码

好的,麻烦您了,抱歉我可能做题太少了,没能明白您的解释。
再次感谢!!!麻烦您了!!!

// Refer to https://leetcode.com/problems/sliding-window-maximum/
interface SlidingWindowMax {
	void add(int num); 
	void pop();
	int max();
}

		int m, n;
		int[][] matrix;
		int[][] res;
		SlidingWindowMax[] cols = new SlidingWindowMax[m];
		for (int endRow = 0; endRow < m; endRow++) {
			SlidingWindowMax cur = new SlidingWindowMax();
			for (int i = 0; i < n; i++) {
				cols[i].add(matrix[endRow][i]);
				if (endRow >= k - 1) {
					// now we may have square
					cur.add(cols[i].max());
					cols[i].pop();

					if (i >= k - 1) {
						// found square
						res[endRow - k + 1][i - k + 1] = cur.max();
						cur.pop();
					}
				}
			}
		}


思路是把一个column作为一个cell,把2D当成1D做

仔细看了一下,其实跟你这个思路是一样的

谢谢 x老师 麻烦您啦!!!
看了您的思路 code 发现我还有好多要学习的
您的code 是真的简洁明了
谢谢!!