首页 > 试题广场 >

已知一个NxN的矩阵A,求矩阵中所有边长为m的正方形的子矩阵

[问答题]


已知一个NxN的矩阵A,求矩阵中所有边长为m的正方形的子矩阵内元素的中位数。(m<N, m%2=1,正方形中的点必须都在原始矩阵中)

例子:
// m = 3 n = 5
// 01234
݂         //  0 11357
݂         //  1 29429
݂         //  2 38668
݂         //  3 47851
݂         //  4 56342
݂         //  01234
݂         //  @@@##
݂         //  @@@##
݂         //  @@@##
݂         //  #####
݂         //  #####
݂         //  标准答案应该是
݂         //  356
݂         //  666
݂         //  665情况1:m的范围在[1, 10]情况2:m范围不限数值范围在[1, 10]情况3:m范围不限数值范围不限
vector<vector<int>> getMidVal(const vector<vector<int>> &mat, int m);


暴力解,遍历每个正方形,取出正方形中的所有数,因为m%2=1,所以取出的数为3m=3*(2n+1)个,肯定为奇数个,所以中位数总是存在在于数组中一个,对取得的正方形,展开成一维后可以使用快排的思想查找TOP K,这里K=(3m-1)/2,这样每个中位数就可以用O(n)的复杂度找到
发表于 2019-07-31 22:48:23 回复(1)
import java.util.Arrays;

public class Test03 {     public static void main(String [] args) {         squal(3,5);     }     public static void squal(int m,int n) {         int[][] arr= { {1,1,3,5,7}, {2,9,4,2,9} ,{3,8,6,6,8}, {4,7,8,5,1}, {5,6,3,4,2}};         int[] arr2=new int[9];         int a=0;         int b=0;         int count;         int len=(n-m+1);         while(true) {             count=0;             for(int i=b;i<b+m;i++) {                 for(int j=a;j<a+m;j++) {                     arr2[count]=arr[i][j];                     System.out.print(arr[i][j]);                     count++;                 }             }             Arrays.sort(arr2);             System.out.println("\t"+arr2[4]);             a++;             if(a==len) {                 a=0;                 b++;             }             if(b==len) {                 return;             }         }     }
}

发表于 2018-08-03 21:53:20 回复(0)