日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

leetcode 221. Maximal Square | 221. 最大正方形(优化的暴力解法+动态规划解法)

發布時間:2024/2/28 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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個點”,此處待改進…

class Solution {public int maximalSquare(char[][] matrix) {int[][] right = new int[matrix.length][matrix[0].length]; // 向右有多少個連續的1int[][] down = new int[matrix.length][matrix[0].length]; // 向下有多少個連續的1// rightfor (int i = matrix.length - 1; i >= 0; i--) {int count = 0;for (int j = matrix[0].length - 1; j >= 0; j--) {if (matrix[i][j] == '0') count = 0;else count++;right[i][j] = count;}}// downfor (int i = matrix[0].length - 1; i >= 0; i--) {int count = 0;for (int j = matrix.length - 1; j >= 0; j--) {if (matrix[j][i] == '0') count = 0;else count++;down[j][i] = count;}}// checkint area = 0;for (int i = 0; i < matrix.length; i++) {for (int j = 0; j < matrix[0].length; j++) {if (right[i][j] > 0) {int square = right[i][j]; // 正方形最大邊長for (int k = 0; k < right[i][j]; k++) {square = Math.min(square, down[i][j + k]); // 最大邊長要取min 因為受向下連續1個數的限制area = Math.max(area, Math.min((k + 1) * (k + 1), square * square)); // 最大面積要取min 因為受到起點k的距離的限制}}}}return area;} }

附:左神算法配套代碼,實現了上述“只看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. 最大正方形(优化的暴力解法+动态规划解法)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。