LeetCode算法日記 - Day 42: 島嶼數量、島嶼的最大面積

目錄

1. 島嶼數量

1.1 題目解析

1.2 解法

1.3 代碼實現

2.?島嶼的最大面積

2.1 題目解析

2.2 解法

2.3 代碼實現


1. 島嶼數量

https://leetcode.cn/problems/number-of-islands/

給你一個由?'1'(陸地)和?'0'(水)組成的的二維網格,請你計算網格中島嶼的數量。

島嶼總是被水包圍,并且每座島嶼只能由水平方向和/或豎直方向上相鄰的陸地連接形成。

此外,你可以假設該網格的四條邊均被水包圍。

示例 1:

輸入:grid = [['1','1','1','1','0'],['1','1','0','1','0'],['1','1','0','0','0'],['0','0','0','0','0']
]
輸出:1

示例 2:

輸入:grid = [['1','1','0','0','0'],['1','1','0','0','0'],['0','0','1','0','0'],['0','0','0','1','1']
]
輸出:3

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 300
  • grid[i][j]?的值為?'0'?或?'1'

1.1 題目解析

題目本質

  • 在一個 m×n 的 0/1 網格上,統計由上下左右連通的“1”塊的個數;本質是“連通分量計數(四聯通)”。

常規解法

  • 樸素想法:對每個為 ‘1’ 的格子啟動一次遍歷,把與之相連的 ‘1’ 都標記掉,然后計數 +1。遍歷可用 DFS 或 BFS。

問題分析

  • 如果不做“訪問標記(vis)”,同一塊島嶼會被重復啟動遍歷 → 重復計數/超時。

  • 如果標記時機不當(入隊后不立刻標記),同一坐標會被多次入隊 → 隊列暴漲。

  • 邊界獲取不當(先取 grid[0].length 再判斷空矩陣)會 NPE。

  • 復雜度:每格最多訪問一次,理想是 O(mn);只要保證“入隊(或遞歸)前標記”為時機,就不會退化。

思路轉折

  • 要高效、且不重算:

    • 必須維護 vis[m][n] 訪問標記;

    • 必須把標記動作放在“入隊/入棧前”;

    • 必須只在遇到“未訪問的 ‘1’”時啟動一次 BFS/DFS,并在啟動點處給計數器 +1。

  • 這樣“每個格子至多被處理一次”,時間 O(mn)、空間 O(mn)。

1.2 解法

算法思想

  • 遍歷整個網格;每當遇到 grid[i][j]=='1' && !vis[i][j]:

    • 啟動一輪 BFS;

    • BFS 中用隊列彈出當前格,向四鄰擴展,對滿足邊界且為 ‘1’ 且未訪問的坐標:先標記 vis=true,再入隊;

    • 該輪 BFS 結束后,說明整塊島嶼已被吞并,計數 ret++。

i)初始化

  • m = grid.length;若 m==0 直接返回 0。

  • n = grid[0].length;vis = new boolean[m][n];ret = 0。

ii)掃描網格

  • 雙層循環 (i,j);當 grid[i][j]=='1' && !vis[i][j] 時,啟動 BFS(i,j)。

iii)BFS 過程

  • 隊列入起點 (si,sj),立刻標記 vis[si][sj]=true。

  • 不斷出隊 (a,b),向四方向 (a+dx[k], b+dy[k]) 擴展;滿足:

    • 在邊界內、

    • 未訪問、

    • 且為 ‘1’
      先標記再入隊。

    • 隊列清空即該島處理完畢,ret++。

iiii)返回 ret。

易錯點

  • n = grid[0].length 必須放在 m==0 判空之后,否則空矩陣會 NPE。

  • if (grid[i][j]=='1' && !vis[i][j]) 中的 !vis[i][j] 一開始當然都是 true,但第一輪 BFS 會把整塊島都標記為 true,后續再遇到同島格子就不會重復啟動 BFS。

  • 標記時機要在入隊前/時,否則同一坐標可能被多次入隊。

  • 只統計“第一次發現這塊島”的那一刻(啟動 BFS 時)的一次 ret++

  • 注意字符比較用 '1',不要寫成 1

  • 四方向遍歷下標不要寫錯。

  • 不要重復無意義的標記(出隊后再次 vis[a][b]=true 屬于冗余)。

1.3 代碼實現

import java.util.*;class Solution {int[] dx = {0, 0, 1, -1};int[] dy = {1, -1, 0, 0};int m, n;Queue<int[]> q = new LinkedList<>();boolean[][] vis;int ret;public int numIslands(char[][] grid) {m = grid.length;if (m == 0) return 0;            // 先判空,再取 nn = grid[0].length;vis = new boolean[m][n];ret = 0;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == '1' && !vis[i][j]) {bfs(grid, i, j);    // 一次 BFS 吞并一整塊島}}}return ret;}// BFS:以 (si, sj) 為起點吞并整塊島嶼public void bfs(char[][] grid, int si, int sj) {q.clear();                       // 成員隊列:顯式清空更穩妥q.offer(new int[]{si, sj});vis[si][sj] = true;              // 入隊前/時標記,避免重復入隊while (!q.isEmpty()) {int[] cur = q.poll();int a = cur[0], b = cur[1];for (int k = 0; k < 4; k++) {int x = a + dx[k], y = b + dy[k];if (x >= 0 && x < m && y >= 0 && y < n&& !vis[x][y] && grid[x][y] == '1') {vis[x][y] = true;     // 先標記,再入隊q.offer(new int[]{x, y});}}}ret++;                            // 本輪 BFS 結束 → 發現了一座島}
}

復雜度分析

  • 時間復雜度:O(m·n),每個格子最多被入隊/出隊一次,四鄰檢查是常數。

  • 空間復雜度:O(m·n),主要在 vis;隊列最壞可能裝下整層邊界上的若干格子,但受 O(mn) 上界。

2.?島嶼的最大面積

https://leetcode.cn/problems/max-area-of-island/

給你一個大小為?m x n?的二進制矩陣?grid?。

島嶼?是由一些相鄰的?1?(代表土地) 構成的組合,這里的「相鄰」要求兩個?1?必須在?水平或者豎直的四個方向上?相鄰。你可以假設?grid?的四個邊緣都被?0(代表水)包圍著。

島嶼的面積是島上值為?1?的單元格的數目。

計算并返回?grid?中最大的島嶼面積。如果沒有島嶼,則返回面積為?0?。

示例 1:

輸入:grid = [[0,0,1,0,0,0,0,1,0,0,0,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,1,1,0,1,0,0,0,0,0,0,0,0],[0,1,0,0,1,1,0,0,1,0,1,0,0],[0,1,0,0,1,1,0,0,1,1,1,0,0],[0,0,0,0,0,0,0,0,0,0,1,0,0],[0,0,0,0,0,0,0,1,1,1,0,0,0],[0,0,0,0,0,0,0,1,1,0,0,0,0]]
輸出:6
解釋:答案不應該是 11 ,因為島嶼只能包含水平或垂直這四個方向上的 1

示例 2:

輸入:grid = [[0,0,0,0,0,0,0,0]]
輸出:0

提示:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 50
  • grid[i][j]?為?0?或?1

2.1 題目解析

題目本質

  • 在 m×n 的二值矩陣中,按四聯通把為 1 的格子聚合成若干連通分量,返回所有分量的最大節點數,也就是最大島嶼面積。

常規解法

  • 線性掃描整張表,每當遇到未訪問的 1,就從該點出發做一次搜索,把整座島吞并,并統計面積。可用 BFS 或 DFS。

問題分析

  • 如果不做訪問標記,同一島會被多次重復遍歷,時間爆炸。

  • 如果標記時機晚(入隊后才標記,甚至出隊后才標記),同一坐標可能被多次入隊,導致隊列暴漲。

  • 如果把面積計數放在“發現鄰居”時,會漏掉起點,得到 N?1 而不是 N。

  • 判空順序不當會空指針,例如先取 grid[0].length 再判斷 m 是否為 0。

  • 復雜度目標是 O(mn),只要保證每格最多被訪問一次即可。

思路轉折

  • 要想穩定 O(mn):

    • 需要全局 vis 數組去重。

    • 需要在入隊之前標記 vis,保證每格最多入隊一次。

    • 需要把面積計數與“訪問到一個新格子”綁定,最簡單是出隊時加一。

    • 只在遇到 grid[i][j] == 1 且未訪問時啟動一次搜索,吞并整座島并更新答案。

2.2 解法

算法思想

  • 雙層循環掃描網格,遇到未訪問的 1 啟動 BFS。

  • BFS 初始化把起點入隊并立刻標記已訪問。

  • 循環彈出隊頭,面積加一,向四個方向擴展,把滿足邊界、為 1、未訪問的鄰居先標記后入隊。

  • 本輪隊列清空即整座島處理完畢,用該島面積更新全局最大值。

i)初始化

  • m = grid.length,若 m == 0 直接返回 0。

  • n = grid[0].length,初始化 vis[m][n] 為 false。

  • 準備一個整型答案 ret 保存最大面積。

ii)掃描

  • 雙層循環 i, j。

  • 當且僅當 grid[i][j] == 1 且 vis[i][j] 為 false 時,啟動 BFS(i, j)。

iii)BFS 細節

  • 入隊起點并立刻標記 vis[si][sj] = true。

  • while 隊列非空:

    • 彈出一個格子,面積加一。

    • 四方向擴展,滿足邊界、為 1、未訪問的鄰居先標記再入隊。

  • 返回本輪面積。

iiii)更新答案

  • ret = max(ret, 本輪面積)。

iiiii)返回 ret

易錯點

  • 判空順序:必須先判斷 m 是否為 0,再讀取 grid[0].length。

  • 標記時機:必須在入隊之前標記,防止同一坐標被多次入隊。

  • 面積計數位置:推薦在出隊時加一,這樣每訪問一個格子恰好計一次;如果堅持在“發現鄰居”時計數,必須把起點先計入,否則會少一。

  • 鄰居入隊坐標:入隊的是鄰居 (x, y),不要誤把起點 (si, sj) 重新塞回隊列。

  • 只考慮四聯通,不能把對角線當作連通。

  • 類型與比較:本題 grid 是 int[][],比較用 1 與 0;與 char[][] 的版本不要混用。

2.3 代碼實現

import java.util.*;class Solution {Queue<int[]> q = new LinkedList<>(); // 成員隊列,BFS 開始時清空更穩妥int m, n;boolean[][] vis;int[] dx = {0, 0, 1, -1};int[] dy = {1, -1, 0, 0};public int maxAreaOfIsland(int[][] grid) {m = grid.length;if (m == 0) return 0;        // 先判空,避免 NPEn = grid[0].length;vis = new boolean[m][n];int ret = 0, cur = 0;for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == 1 && !vis[i][j]) {cur = 0;                         // 可有可無,這里保持你的風格int tmp = bfs(grid, i, j, cur);  // BFS 返回本島面積ret = Math.max(ret, tmp);}}}return ret;}// BFS 吞并以 (si, sj) 為起點的整座島,返回其面積public int bfs(int[][] grid, int si, int sj, int cur) {q.clear();                     // 成員隊列,使用前先清空q.offer(new int[]{si, sj});vis[si][sj] = true;while (!q.isEmpty()) {int[] num = q.poll();int a = num[0], b = num[1];cur++;                     // 出隊即計數,保證每格計一次for (int i = 0; i < 4; i++) {int x = a + dx[i], y = b + dy[i];if (x >= 0 && x < m && y >= 0 && y < n&& grid[x][y] == 1 && !vis[x][y]) {vis[x][y] = true;          // 入隊前標記q.offer(new int[]{x, y});  // 入隊鄰居坐標}}}return cur;}
}

復雜度分析

  • 時間復雜度:O(mn),每個格子最多被訪問一次,四鄰檢查是常數。

  • 空間復雜度:O(mn),主要為 vis;隊列最壞情況下也不超過 O(mn)。

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

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

相關文章

短波紅外相機在機器視覺檢測方向的應用

短波紅外相機在機器視覺檢測方向的應用短波紅外相機&#xff1a;機器視覺的“低成本突破者”一、打破成本困局&#xff1a;短波紅外的“平民化”革新二、核心技術&#xff1a;有機材料的“硬核創新”1. 材料革命&#xff1a;有機感光層的優勢2. 工藝兼容&#xff1a;嫁接成熟CM…

【數據結構與算法】圖 Floyd算法

相關題目&#xff1a; 1334. 閾值距離內鄰居最少的城市 - 力扣&#xff08;LeetCode&#xff09; 資料 &#xff1a; Floyd算法原理及公式推導 - 知乎 Floyd 算法是一種經典的動態規劃算法&#xff0c;用與求解圖中所有頂點之間的最短短路路徑。它由Robert Floyd 于1962…

衛星通信天線的指向精度,含義、測量和計算

衛星通信天線的指向精度&#xff0c;含義、測量和計算我們在衛星通信天線的技術規格書中&#xff0c;都會看到天線指向精度這個指標。一般來說&#xff0c;技術規格書上的天線指向精度的參數是這么寫的&#xff1a;“天線指向精度≤1/10半功率波束帶寬”今天這個文章&#xff0…

基于LSTM與3秒級Tick數據的金融時間序列預測實現

數據加載模塊解析 def load_data(filepath):df pd.read_csv(filepath)return df該函數承擔基礎數據采集職責&#xff0c;通過Pandas庫讀取CSV格式的高頻交易數據&#xff08;典型如股票分筆成交明細&#xff09;。輸入參數為文件路徑字符串&#xff0c;輸出結構化DataFrame對象…

C# --- Field and Property

C# --- Field and Property字段 (Field) vs. 屬性 (Property)Property的聲明初始化方法單例類property錯誤初始化導致線程泄漏字段 (Field) vs. 屬性 (Property) 字段 (Field) - 數據的存儲容器 字段是直接在類或結構中聲明的變量。它是存儲數據的地方&#xff0c;是對象狀態的…

【Python】實現一個文件夾快照與比較工具

1. 工具簡介 在日常開發、項目管理或備份場景中&#xff0c;我們經常需要知道某個文件夾中的文件是否發生變化&#xff0c;例如&#xff1a; 項目源碼是否新增或修改文件&#xff1f;數據集是否被不小心刪除或篡改&#xff1f;備份文件夾是否和上次一致&#xff1f; 本教程將教…

LINUX913 shell:set ip [lindex $argv 0],\r,send_user,spawn ssh root@ip “cat “

問題 獲取公鑰 [codesamba ~]$ cat pub.sh #!/bin/usr/expect set ip "$1" set password 123456 set timeout 20 spawn ssh root192.168.235.100:cat ~/.ssh/id_rsa.pub expect { "yes/no" {send "yes/r";exp_continue} "password:" {…

Acwing算法基礎課--鏈表

一、單鏈表 AcWing 826. 單鏈表 代碼 N 100010 idx 0 e [0] * N ne [0] * N head -1def init():global idx,headidx 0head -1def add_head(x):global idx,heade[idx] xne[idx] headhead idxidx 1def delete(k):ne[k] ne[ne[k]]def add_k(k,x):global idxe[idx] …

AI表征了西方的有界,AI+體現了東方的無界

AI表征了西方的有界&#xff0c;AI體現了東方的無界&#xff0c;試圖通過文化差異的視角來對比傳統AI&#xff08;AI&#xff09;與增強型或融合型AI&#xff08;AI&#xff09;的特征。一、“AI表征了西方的有界”西方的“有界”可以理解為&#xff1a;1、邏輯清晰、結構嚴謹&…

LabVIEW泵輪檢測

?在現代制造業蓬勃發展的浪潮下&#xff0c;汽車行業也迎來了高速發展期。液力變矩器作為實現車輛自動變速的關鍵零件產品&#xff0c;在汽車動力系統中扮演著不可或缺的角色。泵輪作為液力變矩器的核心組成部分&#xff0c;其生產質量直接影響著液力變矩器的性能。因此&#…

RT-DETRv2 中的坐標回歸機制深度解析:為什么用 `sigmoid(inv_sigmoid(ref) + delta)` 而不是除以圖像尺寸?

引言&#xff1a;一個看似簡單的公式&#xff0c;背后藏著工業級設計智慧 在閱讀 RT-DETRv2&#xff08;Real-Time DETR v2&#xff09;源碼時&#xff0c;我曾被一行代碼深深震撼&#xff1a; inter_ref_bbox F.sigmoid(bbox_head[i](output) inverse_sigmoid(ref_points_de…

簡單了解一下GraphRAG

傳統RAG的缺點 當我們將一段文本信息以句子分割后&#xff0c;存入到向量數據庫中。用戶提問“老王喜歡吃什么”&#xff0c;這個問題會與向量數據庫中的許多句子關聯性比較強&#xff0c;能返回準確且具體的信息。 但是&#xff0c;若是問題換成“出現了幾次西瓜”&#xff0c…

HTTP 狀態碼背后的邏輯:從請求到響應的完整流程解析(含完整流程圖)

在日常的 Web 開發與 API 調試中&#xff0c;我們經常會遇到各種 HTTP 狀態碼 ——404 Not Found、401 Unauthorized、500 Internal Server Error... 這些數字背后并非隨機出現&#xff0c;而是服務器處理請求過程中不同階段的 "反饋信號"。理解這些狀態碼的觸發邏輯…

Vue:下拉框多選影響行高

目錄 一、 出現場景二、 解決方案 一、 出現場景 在使用el-select增加multiple屬性進行多選時&#xff0c;會出現高度塌陷的情況 二、 解決方案 首先需要在el-select中增加collapse-tags屬性&#xff0c;并在style中增加如下樣式 方案一 <style scoped> ::v-deep .e…

如何在高通躍龍QCS6490 Arm架構上使用Windows 11 IoT企業版?

1.簡介研華已將高通躍龍QCS6490 技術應用于嵌入式模塊、單板電腦和AI攝像頭等各種規格的嵌入式硬件中。QCS6490平臺支持全面的操作系統生態系統&#xff0c;包括Windows、Ubuntu、Yocto和 Android。Windows 11 IoT企業版是微軟新一代的物聯網操作系統&#xff0c;具有更強的安全…

阿里云國際代理:如何利用RDS構建高可用、可擴展的數據庫架構

講下云數據庫RDS案例解析&#xff0c;若在上云或用云過程中有不懂的&#xff0c;可尋云樞國際yunshuguoji助力免卡上云用云。1、RDS MySQL數據庫代理支持讀寫分離、連接保持、就近訪問、事務拆分、連接池、SSL加密等功能&#xff0c;能夠降低主實例負載&#xff0c;提高實例可用…

C++之特殊類設計

文章目錄前言一、 設計一個不能被拷貝的類1. C98 實現方式2. C11 實現方式二、設計一個只能在堆上創建對象的類1. 方法一&#xff1a;析構函數私有&#xff0c;提供destory接口釋放資源2. 方法二&#xff1a;構造函數私有三、 設計一個只能在棧上創建對象的類1. 實現方式四、設…

TupiTube,一款免費開源的 2D 動畫創作工具

TupiTube&#xff0c;一款免費開源的 2D 動畫創作工具 ** ** 功能 ** &#xff1a;開源、免費的 2D 動畫軟件&#xff0c;界面簡單&#xff0c;支持逐幀動畫、剪紙動畫、定格動畫&#xff0c;能導入素材并導出多種視頻和圖片格式&#xff0c;適合兒童、學生和動畫愛好者入門創作…

MoE架構訓練系統設計:專家并行與門控網絡優化策略

點擊 “AladdinEdu&#xff0c;同學們用得起的【H卡】算力平臺”&#xff0c;注冊即送-H卡級別算力&#xff0c;80G大顯存&#xff0c;按量計費&#xff0c;靈活彈性&#xff0c;頂級配置&#xff0c;學生更享專屬優惠。 摘要 混合專家&#xff08;Mixture of Experts&#xf…

使用Python爬蟲,selenium和requests誰更強?

py爬蟲的話&#xff0c;selenium和reqeusts誰更強&#xff0c;selenium是不是能完全取代requests? 答案基本是可以的&#xff0c;selenium適合動態網頁抓取&#xff0c;因為它可以控制瀏覽器去點擊、加載網頁&#xff0c;requests則比較適合靜態網頁采集&#xff0c;它非常輕…