LeetCode刷題之HOT100之最大正方形

今天下起了暴雨,本以為下午就可以結束的答辯又因為老師開會被推遲。研三的學長走了后我們開始了0元購,收獲頗豐哈哈,做個題

1、題目描述

在這里插入圖片描述

2、算法分析

給定一個矩形,要求最大正方形。第一次見這種題目哈
2024 6/30 嘿嘿,這道題我昨天沒做啦,今天來做,今天中午就待實驗室啦,回去太麻煩了。那么繼續開始做題
我拿到這個題大概知道跟動態規劃有關,然后看了題解,題解給出兩種算法:暴力與DP。那么我們先來看看暴力解法
暴力法是最簡單直觀的做法,具體做法如下:

  1. 遍歷矩陣中的每個元素,每次遇到 1,則將該元素作為正方形的左上角;
  2. 確定正方形的左上角后,根據左上角所在的行和列計算可能的最大正方形的邊長(正方形的范圍不能超出矩陣的行數和列數),在該邊長范圍內尋找只包含 1 的最大正方形;
  3. 每次在下方新增一行以及在右方新增一列,判斷新增的行和列是否滿足所有元素都是 1。

代碼演示:

public int maximalSquare(char[][] matrix) {// 初始化最大正方形的邊長為0 int maxSide = 0;// 如果矩陣為空,則直接返回0if(matrix == null || matrix.length == 0 || matrix[0].length == 0){return maxSide;}// 獲取矩陣的行數和列數int rows = matrix.length, columns  = matrix[0].length;// 遍歷矩陣中的每個元素  for(int i = 0; i < rows; i++){for(int j = 0; j < columns ; j++){// 如果當前元素是'1',則開始嘗試以當前位置為左上角的最大正方形的邊長if(matrix[i][j] == '1'){// 更新maxSide,因為至少可以形成一個邊長為1的正方形maxSide = Math.max(maxSide, 1);// 計算當前位置可能形成的最大正方形的最大可能邊長  // 不能超過矩陣的邊界 int currentMaxSide = Math.min(rows - i, columns  - j );// 嘗試從邊長為1開始,逐漸擴大正方形的邊長for(int k = 1; k < currentMaxSide; k++){// 假設當前邊長k的正方形是可能的boolean flag = true;// 檢查正方形的右下角是否為'0',如果是,則無法形成邊長為k的正方形if(matrix[i + k][j + k] == '0'){break;}// 檢查正方形的右側和下方的邊界是否都為'1'  // 如果有任何一個為'0',則無法形成邊長為k的正方形for(int m = 0; m < k; m++){if(matrix[i + k][j + m] == '0' || matrix[i + m][j + k] == '0'){flag = false;break;}}// 如果能形成邊長為k的正方形,則更新maxSideif(flag){maxSide = Math.max(maxSide, k + 1);// 如果不能形成邊長為k的正方形,則無需繼續嘗試更大的邊長}else{break;}}}}}// 計算最大正方形的面積并返回int maxSquare = maxSide * maxSide;return maxSquare;}

暴力解法的時間復雜度: O ( m n min ? ( m , n ) 2 ) O(mn\min(m,n)^2) O(mnmin(m,n)2),其中 m 和 n 是矩陣的行數和列數。空間復雜度:O(1)。額外使用的空間復雜度為常數。

可以看到空間復雜度很高了,那么我們來看看動態規劃是怎么解決的。

可以使用動態規劃降低時間復雜度。

  • 我們用 dp(i,j) 表示以 (i,j) 為右下角,且只包含 1 的正方形的邊長最大值。如果我們能計算出所有
    dp(i,j) 的值,那么其中的最大值即為矩陣中只包含 1 的正方形的邊長最大值,其平方即為最大正方形的面積。
  • 那么如何計算 dp 中的每個元素值呢?對于每個位置 (i,j),檢查在矩陣中該位置的值:
  • 如果該位置的值是 0,則 dp(i,j)=0,因為當前位置不可能在由 1 組成的正方形中;
  • 如果該位置的值是 1,則 dp(i,j) 的值由其上方左方左上方的三個相鄰位置的 dp值決定。具體而言,當前位置的元素值等于三個相鄰位置的元素中的最小值加 1,狀態轉移方程如下:
dp(i,j) = min(dp(i ? 1,j), dp(i ? 1,j ? 1), dp(i,j ? 1) ) + 1

此外,還需要考慮邊界條件。如果 ij 中至少有一個為 0,則以位置 (i,j) 為右下角的最大正方形的邊長只能是 1,因此 dp(i,j)=1

3、代碼

public int maximalSquare(char[][] matrix) {// 初始化最大正方形的邊長為0int maxSide = 0;// 如果矩陣為空,或者沒有行或列,則直接返回0if(matrix == null || matrix.length == 0 || matrix[0].length == 0){return maxSide;}// 獲取矩陣的行數和列數int rows = matrix.length, columns = matrix[0].length;// 創建一個與原始矩陣大小相同的二維dp數組,用于存儲每個位置的最大正方形邊長int[][] dp = new int[rows][columns];// 遍歷矩陣的每一個位置for(int i = 0; i < rows; i++){for(int j = 0 ; j < columns; j++){// 如果當前位置是'1' if(matrix[i][j] == '1'){// 如果當前位置是第一行或第一列,則最大正方形邊長只能是1 if(i == 0 || j == 0){dp[i][j] = 1;}else{// 否則,當前位置的最大正方形邊長取決于其上方、左方和左上方的最小邊長,并加1  // 因為我們要考慮的是由'1'組成的正方形dp[i][j] = Math.min(Math.min(dp[i - 1][j], dp[i][j - 1]), dp[i - 1][j - 1]) + 1;}// 更新最大正方形的邊長maxSide = Math.max(maxSide, dp[i][j]);}               }}// 計算最大正方形的面積(邊長的平方)int maxSquare = maxSide * maxSide;// 返回最大正方形的面積return maxSquare;}

這里的dp思想跟我之前做的一道最短路徑思想是一樣的。通過填充一個與原始矩陣大小相同的dp數組來記錄每個位置的最大正方形邊長。最終,返回的是最大正方形的面積,而不是邊長。

4、復雜度分析

  • 時間復雜度:O(mn),其中 m 和 n 是矩陣的行數和列數。需要遍歷原始矩陣中的每個元素計算 dp 的值。
  • 空間復雜度:O(mn),其中 m 和 n 是矩陣的行數和列數。創建了一個和原始矩陣大小相同的矩陣 dp。由于狀態轉移方程中的 dp(i,j) 由其上方、左方和左上方的三個相鄰位置的 dp 值決定,因此可以使用兩個一維數組進行狀態轉移,空間復雜度優化至 O(n)。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/38207.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/38207.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/38207.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

實體零售連鎖企業如何通過物流接口實現數智化轉型升級?

在電子商務浪潮的持續沖擊下&#xff0c;傳統的實體零售行業面臨著巨大的挑戰。為了在線上線下融合的新零售時代保持競爭力&#xff0c;眾多實體零售企業積極尋求數字化轉型的突破。 某中國零售連鎖百強企業近年來致力于打造自有品牌的線上銷售體系&#xff0c;自2021年8月起接…

深入解析 gRPC 的重連機制

目錄 什么是 gRPC 重連機制 gRPC 重連策略 gRPC 重連參數 gRPC 重連機制原理 重連機制的注意事項 小結 gRPC 的重連機制是確保客戶端在連接斷開后能夠自動重新連接到服務器的一種機制&#xff0c;對于分布式系統和微服務架構中的高可用性和容錯性至關重要。 什么是 gRPC…

Python數據分析-風濕關節炎生存分析

一、研究背景和意義 類風濕關節炎&#xff08;RA&#xff09;是一種慢性炎癥性疾病&#xff0c;主要影響關節&#xff0c;但也可能影響身體的其他部分。RA的病因尚不完全清楚&#xff0c;但已知其涉及免疫系統的異常反應。患者的免疫系統錯誤地攻擊自身的關節組織&#xff0c;…

HCIA4.9-4.19筆記

通訊——雙向的&#xff0c;必須保證有來有回才能成功。 當拓撲圖中的所有路由器擁有拓撲圖中的所有網段時&#xff0c;即可實現全網通。 路由器獲取位置網段的方法 靜態路由 由管理員手寫的路由條目 動態路由 所有路由器上運行同一種動態路由協議&#xff0c;之后通過路…

Python 3 注釋

Python 3 注釋 在編程中,注釋是一種用于解釋代碼和提供上下文的方式,它對代碼的執行沒有影響。Python 3 支持多種類型的注釋,包括單行注釋和多行注釋。注釋對于提高代碼的可讀性和維護性非常重要,特別是在團隊合作和大型項目中。 單行注釋 單行注釋以井號(#)開頭,用于…

C++ 成員模板類

#include <iostream> // 包含頭文件。 using namespace std; // 指定缺省的命名空間。template<class T1, class T2> class AA // 類模板AA。 { public:T1 m_x;T2 m_y;AA(const T1 x, const T2 y) : m_x(x), m_y(y) {}void show() { c…

Python 學習之簡單的程序(三)

編寫簡單的Python程序是鞏固基礎的好方法。下面我將給出幾個簡單的Python程序示例&#xff0c;涵蓋了基本的數據類型、控制流、函數和文件操作。 示例1&#xff1a;Hello, World! 這是最簡單的Python程序&#xff0c;用于打印出 "Hello, World!"。 print("He…

初學者指南:如何選擇嵌入式Linux和單片機(MCU)

前言 在嵌入式系統開發領域&#xff0c;選擇合適的平臺是項目成功的關鍵之一。對于初學者來說&#xff0c;如何在嵌入式Linux和單片機&#xff08;MCU&#xff09;之間做出選擇可能是一項艱巨的任務。本文將詳細解釋這兩種平臺的特點、優缺點&#xff0c;以及在不同應用場景中…

低代碼表單配置平臺替代普通表單配置平臺,前端部分重構的設計和思路

前言 最近將公司的舊表單配置平臺重構為低代碼表單配置平臺&#xff0c;這里記錄一下這個過程的設計和思路&#xff0c;不涉及具體的代碼&#xff1b;另外這篇文章基本只涉及前端部分&#xff0c;也不涉及與后端數據交互部分。 需求 固化的表單配置平臺 -> 靈活的表單配置…

TreeMap 和 TreeSet 的基本情況、特性以及使用場景,并對比它們與 HashMap 和 HashSet

TreeMap 基本情況 實現&#xff1a;基于紅黑樹實現的 NavigableMap。排序&#xff1a;鍵按自然順序或自定義順序&#xff08;通過 Comparator&#xff09;排序。特性&#xff1a; 不允許 null 鍵&#xff0c;但允許 null 值。保證鍵有序。迭代時按排序順序。復雜度&#xff1…

【最長公共前綴 動態規劃】2430. 對字母串可執行的最大刪除數

如果有不明白的&#xff0c;請加文末QQ群。 本文涉及知識點 最長公共前綴 動態規劃 動態規劃匯總 LeetCode 2430. 對字母串可執行的最大刪除數 給你一個僅由小寫英文字母組成的字符串 s 。在一步操作中&#xff0c;你可以&#xff1a; 刪除 整個字符串 s &#xff0c;或者 …

vscode中的字符縮進問題

問題描述&#xff1a; 如圖當一行代碼中出現不同類型的字符時&#xff0c;使用tab縮只是插入了固定數量&#xff08;默認4&#xff09;的空格或制表符&#xff0c;仍然無法對齊。 解決方法&#xff1a; vscode找到設置&#xff0c;搜索fontFamily&#xff0c;對應輸入框寫入mon…

Linux系統編程--進程間通信

目錄 1. 介紹 1.1 進程間通信的目的 1.2 進程間通信的分類 2. 管道 2.1 什么是管道 2.2 匿名管道 2.2.1 接口 2.2.2 步驟--以父子進程通信為例 2.2.3 站在文件描述符角度-深度理解 2.2.4 管道代碼 2.2.5 讀寫特征 2.2.6 管道特征 2.3 命名管道 2.3.1 接口 2.3.2…

集成平臺建設方案(Doc原件)

基礎支撐平臺作為系統總體架構的核心&#xff0c;不僅要促進與各應用子系統和第三方系統的順暢交互&#xff0c;還需確保內部業務在該平臺上能夠靈活擴展。針對這一需求&#xff0c;我們對基礎支撐平臺提出了以下要求&#xff1a; (1) 平臺需基于其基礎架構&#xff0c;為多源異…

python基礎:設置代碼格式

隨著編寫的程序越來越長&#xff0c;有必要了解一些代碼格式的約定&#xff0c;讓你的代碼盡可以能易于閱讀。 python代碼編寫規范為PEP8&#xff0c;有興趣的朋友可以下載觀看&#xff0c;這里僅作簡要說明。 1、縮進 PEP8建議每級縮進都使用4個空格。多數情況下編程語言的…

vscode-創建vue3項目-修改暗黑主題-常見錯誤-element插件標簽-用法涉及問題

文章目錄 1.vscode創建運行編譯vue3項目2.添加項目資源3.添加element-plus元素4.修改為暗黑主題4.1.在main.js主文件中引入暗黑樣式4.2.添加自定義樣式文件4.3.html頁面html標簽添加樣式 5.常見錯誤5.1.未使用變量5.2.關閉typescript檢查5.3.調試器支持5.4.允許未到達代碼和未定…

UE5的安裝與基本操作(一)

文章目錄 前言安裝UE5新建第一個游戲項目基本游覽方式對目標進行變換各種變換對齊 快速定位目標 總結 前言 Unreal Engine 5 (UE5) 是一款由 Epic Games 開發的實時 3D 創作平臺&#xff0c;用于制作游戲、電影、動畫、建筑可視化和其他類型的交互式體驗。UE5 提供了一系列強大…

Flutter第十五彈 Flutter插件

目標&#xff1a; 1.Flutter插件是什么&#xff1f;有什么作用&#xff1f; 插件 (plugin) 是 package 的一種&#xff0c;全稱是 plugin package&#xff0c;我們簡稱為 plugin&#xff0c;中文叫插件。 2.怎么創建Flutter插件&#xff1f; 一、什么是插件 在flutter中&am…

【成都活動邀請函】7月6 | PowerData 數字經濟-“成都“開源行!

【成都活動邀請函】7月6 | PowerData 數字經濟-"成都"開源行&#xff01; 活動介紹活動信息線上直播掃碼報名往期活動回顧專注數據開源&#xff0c;推動大數據發展 活動介紹 九天開出一成都&#xff0c;萬戶千門入畫圖。 自古以來&#xff0c;成都便是國家發展的重要…

第2章-Python編程基礎

#本章目標 1&#xff0c;了解什么是計算機程序 2&#xff0c;了解什么是編程語言 3&#xff0c;了解編程語言的分類 4&#xff0c;了解靜態語言與腳本語言的區別 5&#xff0c;掌握IPO程序編寫方法 6&#xff0c;熟練應用輸出函數print與輸入函數input 7&#xff0c;掌握Python…