边界为1的最大子方阵(模拟+动态规划)

 分析:这里不使用直接暴力枚举的方法,而是使用最大最先算的最优算法。这里的思考方式值得学习。

方法一:使用模拟的方法,模拟寻找过程(从大到小顺序查找,找到就停止)

public class Main {
	public static int a[][] = {
		{1,1,1,1,1,1},
		{1,0,0,0,1,1},
		{1,0,0,0,1,1},
		{1,0,0,0,1,1},
		{1,1,1,1,1,1},
		{1,0,1,1,1,1}
	};

	public static void main(String[] args) {
        findMaxphalanx();
	}

	private static void findMaxphalanx() {
		
		int N = a.length;
		int n = N;
		//从最大的开始找,当找到就结束
	out2:	while(n > 0) {
			//起始点
		out1:	for(int i = 0; i < N; i ++) {
				for(int j = 0; j < N; j ++) {
					if((i + n > N ) || (j + n > N)) {
						continue out1;
					}
					//开始模拟走圈
					int nr = i + n;
					int nc = j + n;
					//上
					for(int k = j; k < nc; k ++) {
						if(a[i][k] == 0) {
							continue out1;
						}
					}
					//右
					for(int k = i; k < nr; k ++) {
						if(a[k][nc - 1] == 0) {
							continue out1;
						}
					}
					//下
					for(int k = nc - 1; k > 0; k --) {
						if(a[nr - 1][k] == 0) {
							continue out1;
						}
					}
					//左
					for(int k = nr - 1; k > 0; k --) {
						if(a[k][j] == 0) {
							continue out1;
						}
					}
					System.out.println(n);
					break out2;
				}
				
			}
		    
			n --;
		}
	}

}

优化方法二:在之前用动态规划的方法先生成一个辅助查看的数组,根据数组来看是否符合

public class Main {

	public static int a[][] = {
			{1,1,1,1,1,1},
			{1,0,0,0,1,1},
			{1,0,0,0,1,1},
			{1,0,0,0,1,1},
			{1,0,1,1,1,1},
			{1,1,0,1,1,1}
		};
        public static int N = a.length;
		public static void main(String[] args) {
	        creatPhaTemp();
		}

		private static void creatPhaTemp() {
			
			int temp[][][] = new int[N][N][2];
			//int n = N;
			//注意动态规划是从右下向左上方生成矩阵(右 + 下的和)
			for(int i = N - 1; i >= 0; i --) {
				for(int j = N - 1; j >= 0; j --) {
					if(i == N - 1) {
						if(j == N - 1) {
							if(a[N - 1][j] == 1) {
								temp[N - 1][j][0] = 1;
								temp[N - 1][j][1] = 1;
							}
							else {
								temp[N - 1][j][0] = 0;
								temp[N - 1][j][1] = 0;
							}
						}
						else {
							if(a[N - 1][j] == 1) {
								temp[i][j][0] = temp[i][j + 1][0] + 1;
								temp[i][j][1] = 1;
							}
							else {
								temp[i][j][0] = 0;
								temp[i][j][1] = 0;
							}
						}
					}
					else if(j == N -1) {
						if(a[i][j] == 1) {							
							temp[i][j][0] = 1;
							temp[i][j][1] = temp[i + 1][j][1] + 1;
						}
						else {
							temp[i][j][0] = 0;
							temp[i][j][1] = 0;
						}
					}
					else {
						if(a[i][j] == 1) {							
							temp[i][j][0] = temp[i][j + 1][0] + 1;
							temp[i][j][1] = temp[i + 1][j][1] + 1;
						}
						else {
							temp[i][j][0] = 0;
							temp[i][j][1] = 0;
						}
					}
				}
			}
			
			for(int i = 0; i < N; i ++) {
				for(int j = 0; j < N; j ++) {
					System.out.print(temp[i][j][0] + "," + temp[i][j][1] + " ");
				}
				System.out.println();
			}
			for(int i = N; i >= 0; i --) {
				if(check(temp , i )) return;
			}
			
		}

		private static boolean check(int[][][] temp ,int n) {
			for(int i = 0; i < N; i ++) {
				for(int j = 0; j < N; j ++) {
					int nr = i + n - 1;
					int nc = j + n - 1;
					if(temp[i][j][0] >= n
					   &&temp[i][j][1] >= n
					   &&temp[i][nc][1] >= n
					   &&temp[nr][j][0] >= n
					   )
						{
						System.out.println(n);
						return true;
						}
						
				}
			}
			return false;
		}

		
}

猜你喜欢

转载自blog.csdn.net/qq_42794545/article/details/89405068