leetcode 221. Maximal Square | 221. 最大正方形(优化的暴力解法+动态规划解法)
生活随笔
收集整理的這篇文章主要介紹了
leetcode 221. Maximal Square | 221. 最大正方形(优化的暴力解法+动态规划解法)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
題目
https://leetcode.com/problems/maximal-square/
題解
方法1:最暴力解 O((m*n)^2)
public class Solution {public int maximalSquare(char[][] matrix) {int rows = matrix.length, cols = rows > 0 ? matrix[0].length : 0;int maxsqlen = 0;for (int i = 0; i < rows; i++) {for (int j = 0; j < cols; j++) {if (matrix[i][j] == '1') {int sqlen = 1;boolean flag = true;while (sqlen + i < rows && sqlen + j < cols && flag) {for (int k = j; k <= sqlen + j; k++) {if (matrix[i + sqlen][k] == '0') {flag = false;break;}}for (int k = i; k <= sqlen + i; k++) {if (matrix[k][j + sqlen] == '0') {flag = false;break;}}if (flag)sqlen++;}if (maxsqlen < sqlen) {maxsqlen = sqlen;}}}}return maxsqlen * maxsqlen;} }方法2:優化的暴力解法 O((m^2)*n)
雖然時間復雜度相同,但本代碼沒有實現上述“只看4個點”,此處待改進…
附:左神算法配套代碼,實現了上述“只看4個點”,供參考。
package chapter_8_arrayandmatrix;public class Problem_21_MaxOneBorderSize {public static void setBorderMap(int[][] m, int[][] right, int[][] down) {int r = m.length;int c = m[0].length;if (m[r - 1][c - 1] == 1) {right[r - 1][c - 1] = 1;down[r - 1][c - 1] = 1;}for (int i = r - 2; i != -1; i--) {if (m[i][c - 1] == 1) {right[i][c - 1] = 1;down[i][c - 1] = down[i + 1][c - 1] + 1;}}for (int i = c - 2; i != -1; i--) {if (m[r - 1][i] == 1) {right[r - 1][i] = right[r - 1][i + 1] + 1;down[r - 1][i] = 1;}}for (int i = r - 2; i != -1; i--) {for (int j = c - 2; j != -1; j--) {if (m[i][j] == 1) {right[i][j] = right[i][j + 1] + 1;down[i][j] = down[i + 1][j] + 1;}}}}public static int getMaxSize(int[][] m) {int[][] right = new int[m.length][m[0].length];int[][] down = new int[m.length][m[0].length];setBorderMap(m, right, down);for (int size = Math.min(m.length, m[0].length); size != 0; size--) {if (hasSizeOfBorder(size, right, down)) {return size;}}return 0;}public static boolean hasSizeOfBorder(int size, int[][] right, int[][] down) {for (int i = 0; i != right.length - size + 1; i++) {for (int j = 0; j != right[0].length - size + 1; j++) {if (right[i][j] >= size && down[i][j] >= size&& right[i + size - 1][j] >= size&& down[i][j + size - 1] >= size) {return true;}}}return false;}public static int[][] generateRandom01Matrix(int rowSize, int colSize) {int[][] res = new int[rowSize][colSize];for (int i = 0; i != rowSize; i++) {for (int j = 0; j != colSize; j++) {res[i][j] = (int) (Math.random() * 2);}}return res;}public static void printMatrix(int[][] matrix) {for (int i = 0; i != matrix.length; i++) {for (int j = 0; j != matrix[0].length; j++) {System.out.print(matrix[i][j] + " ");}System.out.println();}}public static void main(String[] args) {int[][] matrix = generateRandom01Matrix(7, 8);printMatrix(matrix);System.out.println(getMaxSize(matrix));} }方法3:動態規劃
思路來源:leetcode 官方題解
動態規劃最重要的就是想清楚 d[i,j] 代表著什么,這個太重要了。
這道題中的 d[i, j] 代表的是,以坐標點(i,j) 為右下角的最大正方形,如果說你的 d[i,j] 是想這個區域中最大的正方形,那可就麻煩太多了。
官方題解代碼:
public class Solution {public int maximalSquare(char[][] matrix) {int rows = matrix.length, cols = rows > 0 ? matrix[0].length : 0;int[][] dp = new int[rows + 1][cols + 1];int maxsqlen = 0;for (int i = 1; i <= rows; i++) {for (int j = 1; j <= cols; j++) {if (matrix[i-1][j-1] == '1'){dp[i][j] = Math.min(Math.min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;maxsqlen = Math.max(maxsqlen, dp[i][j]);}}}return maxsqlen * maxsqlen;} }方法4:動態規劃的優化解法
public class Solution {public int maximalSquare(char[][] matrix) {int rows = matrix.length, cols = rows > 0 ? matrix[0].length : 0;int[] dp = new int[cols + 1];int maxsqlen = 0, prev = 0;for (int i = 1; i <= rows; i++) {for (int j = 1; j <= cols; j++) {int temp = dp[j];if (matrix[i - 1][j - 1] == '1') {dp[j] = Math.min(Math.min(dp[j - 1], prev), dp[j]) + 1;maxsqlen = Math.max(maxsqlen, dp[j]);} else {dp[j] = 0;}prev = temp;}}return maxsqlen * maxsqlen;} }總結
以上是生活随笔為你收集整理的leetcode 221. Maximal Square | 221. 最大正方形(优化的暴力解法+动态规划解法)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: leetcode 220. Contai
- 下一篇: 如何 ssh 到内网服务器?