Leetcode200. 島嶼數量

Every day a Leetcode

題目來源:200. 島嶼數量

解法1:深度優先搜索

設目前指針指向一個島嶼中的某一點 (i, j),尋找包括此點的島嶼邊界。

從 (i, j) 向此點的上下左右 (i+1,j),(i-1,j),(i,j+1),(i,j-1) 做深度搜索。

終止條件:

  1. (i, j) 越過矩陣邊界;
  2. grid[i][j] == 0,代表此分支已越過島嶼邊界。

搜索島嶼的同時,執行 grid[i][j] = ‘0’,即將島嶼所有節點刪除,以免之后重復搜索相同島嶼。

遍歷整個矩陣,當遇到 grid[i][j] == ‘1’ 時,從此點開始做深度優先搜索 dfs,島嶼數 count + 1 且在深度優先搜索中刪除此島嶼。

最終返回島嶼數 count 即可。

代碼:

/** @lc app=leetcode.cn id=200 lang=cpp** [200] 島嶼數量*/// @lc code=start// 深度優先搜索class Solution
{
private:const int dx[4] = {-1, 0, 1, 0};const int dy[4] = {0, 1, 0, -1};public:int numIslands(vector<vector<char>> &grid){if (grid.empty())return 0;int m = grid.size(), n = m ? grid[0].size() : 0;int islands = 0;for (int i = 0; i < m; i++)for (int j = 0; j < n; j++)if (grid[i][j] == '1'){islands++;dfs(grid, i, j);}return islands;}// 輔函數 - 深度優先搜索void dfs(vector<vector<char>> &grid, int r, int c){if (r < 0 || r >= grid.size() || c < 0 || c >= grid[0].size() || grid[r][c] == '0')return;grid[r][c] = '0';for (int i = 0; i < 4; i++){int x = dx[i], y = dy[i];dfs(grid, r + x, c + y);}}
};
// @lc code=end

結果:

在這里插入圖片描述

復雜度分析:

時間復雜度:O(m*n),其中 m 和 n 分別是二維數組 grid 的行數和列數。

空間復雜度:O(m*n),其中 m 和 n 分別是二維數組 grid 的行數和列數。在最壞情況下,整個網格均為陸地,深度優先搜索的深度達到 m*n。

解法2:廣度優先搜索

同樣地,我們也可以使用廣度優先搜索代替深度優先搜索。

為了求出島嶼的數量,我們可以掃描整個二維網格。如果一個位置為 1,則將其加入隊列,開始進行廣度優先搜索。在廣度優先搜索的過程中,每個搜索到的 1 都會被重新標記為 0。直到隊列為空,搜索結束。

最終島嶼的數量就是我們進行廣度優先搜索的次數。

代碼:

class Solution
{
public:int numIslands(vector<vector<char>> &grid){if (grid.empty())return 0;int m = grid.size(), n = m ? grid[0].size() : 0;int islands = 0;for (int r = 0; r < m; r++)for (int c = 0; c < n; c++)if (grid[r][c] == '1'){islands++;grid[r][c] = '0';queue<pair<int, int>> neighbors;neighbors.push({r, c});while (!neighbors.empty()){auto rc = neighbors.front();neighbors.pop();int row = rc.first, col = rc.second;if (row - 1 >= 0 && grid[row - 1][col] == '1'){neighbors.push({row - 1, col});grid[row - 1][col] = '0';}if (row + 1 < m && grid[row + 1][col] == '1'){neighbors.push({row + 1, col});grid[row + 1][col] = '0';}if (col - 1 >= 0 && grid[row][col - 1] == '1'){neighbors.push({row, col - 1});grid[row][col - 1] = '0';}if (col + 1 < n && grid[row][col + 1] == '1'){neighbors.push({row, col + 1});grid[row][col + 1] = '0';}}}return islands;}
};

結果:

在這里插入圖片描述

復雜度分析:

時間復雜度:O(m*n),其中 m 和 n 分別是二維數組 grid 的行數和列數。

空間復雜度:O(min?(m, n)),其中 m 和 n 分別是二維數組 grid 的行數和列數。在最壞情況下,整個網格均為陸地,隊列的大小可以達到 min?(m, n)。

解法3:并查集

同樣地,我們也可以使用并查集代替搜索。

為了求出島嶼的數量,我們可以掃描整個二維網格。如果一個位置為 1,則將其與相鄰四個方向上的 1 在并查集中進行合并。

最終島嶼的數量就是并查集中連通分量的數目。

代碼:

class UnionFind {
public:UnionFind(vector<vector<char>>& grid) {count = 0;int m = grid.size();int n = grid[0].size();for (int i = 0; i < m; ++i) {for (int j = 0; j < n; ++j) {if (grid[i][j] == '1') {parent.push_back(i * n + j);++count;}else {parent.push_back(-1);}rank.push_back(0);}}}int find(int i) {if (parent[i] != i) {parent[i] = find(parent[i]);}return parent[i];}void unite(int x, int y) {int rootx = find(x);int rooty = find(y);if (rootx != rooty) {if (rank[rootx] < rank[rooty]) {swap(rootx, rooty);}parent[rooty] = rootx;if (rank[rootx] == rank[rooty]) rank[rootx] += 1;--count;}}int getCount() const {return count;}private:vector<int> parent;vector<int> rank;int count;
};class Solution {
public:int numIslands(vector<vector<char>>& grid) {int nr = grid.size();if (!nr) return 0;int nc = grid[0].size();UnionFind uf(grid);int num_islands = 0;for (int r = 0; r < nr; ++r) {for (int c = 0; c < nc; ++c) {if (grid[r][c] == '1') {grid[r][c] = '0';if (r - 1 >= 0 && grid[r-1][c] == '1') uf.unite(r * nc + c, (r-1) * nc + c);if (r + 1 < nr && grid[r+1][c] == '1') uf.unite(r * nc + c, (r+1) * nc + c);if (c - 1 >= 0 && grid[r][c-1] == '1') uf.unite(r * nc + c, r * nc + c - 1);if (c + 1 < nc && grid[r][c+1] == '1') uf.unite(r * nc + c, r * nc + c + 1);}}}return uf.getCount();}
};

復雜度分析:

在這里插入圖片描述

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

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

相關文章

“圓柱-計算公式“技術支持網址

該軟件可以計算圓柱的底面圓周長、底面積、側面積和體積。 您在使用中有遇到任何問題都可以和我們聯系。我們會在第一時間回復您。 郵箱地址&#xff1a;elmo30zeongmail.com 謝謝&#xff01;

如何將本地websocket發布至公網并實現遠程訪問?

本地websocket服務端暴露至公網訪問【cpolar內網穿透】 文章目錄 本地websocket服務端暴露至公網訪問【cpolar內網穿透】1. Java 服務端demo環境2. 在pom文件引入第三包封裝的netty框架maven坐標3. 創建服務端,以接口模式調用,方便外部調用4. 啟動服務,出現以下信息表示啟動成功…

VR云游:讓旅游產業插上數字化翅膀,打造地方名片

自多地入冬降溫以來&#xff0c;泡溫泉成了許多人周末度假的選擇&#xff0c;在氣溫持續走低的趨勢下&#xff0c;溫泉游也迎來了旺季&#xff1b;但是依舊有些地區溫度依舊溫暖&#xff0c;例如南京的梧桐美景也吸引了不少游客前去打卡&#xff0c;大家穿著漢服與金黃的樹葉合…

【AI考證筆記】NO.1人工智能的基礎概念

以下部分內容來自于百度智能云人才認證培訓講義&#xff0c;騰訊等也有人工智能類似的講義&#xff0c;限時免費&#xff0c;也就是不報考&#xff0c;也能系統學習&#xff0c;課程做的都是不錯的。有感興趣的朋友&#xff0c;可以去檢索學習。 本系列是學習筆記&#xff0c;…

6個常用的聚類評價指標

評估聚類結果的有效性&#xff0c;即聚類評估或驗證&#xff0c;對于聚類應用程序的成功至關重要。它可以確保聚類算法在數據中識別出有意義的聚類&#xff0c;還可以用來確定哪種聚類算法最適合特定的數據集和任務&#xff0c;并調優這些算法的超參數(例如k-means中的聚類數量…

C語言——從鍵盤輸人三角形的三個邊長 a、b、c,求出三角形的面積。

從鍵盤輸人三角形的三個邊長 a、b、c,求出三角形的面積。求三角形的面積用公式areasqrt(s*(s-a)*(s-b)*(s-c)),其中 s1/2(a十bc)。注:要求對輸人三角形的三個邊長做出有效性判斷。 #define _CRT_SECURE_NO_WARNINGS 1#include<stdio.h> #include<math.h> int main…

從word復制內容到wangEditor富文本框的時候會把html標簽也復制過來,如果只想實現直接復制純文本,有什么好的實現方式

從word復制內容到wangEditor富文本框的時候會把html標簽也復制過來&#xff0c;如果只想實現直接復制純文本&#xff0c;有什么好的實現方式&#xff1f; 將 Word 中的內容復制到富文本編輯器時&#xff0c;常常會帶有大量的 HTML 標簽和樣式&#xff0c;這可能導致不必要的格式…

前置微小信號放大器在生物醫學中有哪些應用

前置微小信號放大器在生物醫學領域中具有廣泛的應用。生物醫學信號通常具有較小的振幅和較低的幅頻響應&#xff0c;因此需要借助放大器來增強信號以便進行準確的測量、監測和分析。以下是前置微小信號放大器在生物醫學中的主要應用。 心電圖&#xff08;ECG&#xff09;放大器…

Spring第一課,了解IDEA里面的文件,回顧Cookie和Session,獲取Session,Cookie,Header的方式

目錄 IDEA第一課&#xff08;熟悉里面內容&#xff09; 建立連接 -RequestMapping 路由映射 請求 1.傳遞單個參數?編輯 2.多個參數?編輯 3.傳遞數組 4.傳遞一個集合&#xff0c;但是這里我們傳遞的時候發生了500的錯誤 簡單介紹JSON 回顧Cookie和S…

js檢測dom變化的方法:MutationObserver

前言 檢測一個原生dom的變化,如一個div的顏色,大小,所在位置,內部元素的屬性是否變化,更深層dom樹上的變化等等。 都可以使用一個window上暴露出來的一個api:MutationObserver 語法 官方地址:MutationObserver.MutationObserver() - Web API 接口參考 | MDN 使用new Mutat…

【大數據】Docker部署HMS(Hive Metastore Service)并使用Trino訪問Minio

本文參考鏈接置頂&#xff1a; Presto使用Docker獨立運行Hive Standalone Metastore管理MinIO&#xff08;S3&#xff09;_hive minio_BigDataToAI的博客-CSDN博客 一. 背景 團隊要升級大數據架構&#xff0c;需要摒棄hadoop&#xff0c;底層使用Minio做存儲&#xff0c;應用…

干貨 | 攜程酒店基于血緣元數據的數據流程優化實踐

作者簡介 九號&#xff0c;攜程數據技術專家&#xff0c;關注數據倉庫架構、數據湖、流式計算、數據治理。 一、背景 元數據MetaData狹義的解釋是用來描述數據的數據&#xff0c;廣義的來看&#xff0c;除了業務邏輯直接讀寫處理的那些業務數據&#xff0c;所有其它用來維持整個…

kafka詳細講解與安裝

Kafka是一種分布式流處理平臺&#xff0c;具有高吞吐量、可擴展性和容錯性。它最初由LinkedIn開發&#xff0c;現已成為Apache軟件基金會的頂級項目。Kafka廣泛應用于實時數據流處理、日志收集、消息隊列等場景。 以下是關于Kafka的簡要講解和安裝步驟&#xff1a; 一、Kafka…

ubuntu22.04 arrch64版操作系統編譯zlmediakit

腳本 系統沒有cmake&#xff0c;需要通過apt先進行下載&#xff0c;下面的腳本已經包含了 # 安裝依賴 gcc-c.x86_64 這個不加的話會有問題 sudo yum -y install gcc gcc-c libssl-dev libsdl-dev libavcodec-dev libavutil-dev ffmpeg git openssl-devel gcc-c.x86_64 ca…

csrf漏洞修復

漏洞說明&#xff1a;通過篡改請求頭中的Referer值依舊能夠訪問到接口。 通過http請求頭里面的Referer隨意訪問接口 通過下面兩個代碼類程序來實現你的程序不會被攻擊&#xff0c;里面有兩個實體&#xff0c;如果你感覺這個程序對你有用&#xff0c;聯系我&#xff0c;我私發…

CentOS 7 安裝 Weblogic 14 版本

安裝JDK程序 注意&#xff1a;安裝weblogic前&#xff0c;先安裝JDK&#xff01;&#xff08;要求jdk(1.7以上)&#xff09;&#xff1a; 一、創建用戶組weblogic及用戶weblogic groupadd weblogic useradd -g weblogic weblogic二、將下載好的jdk及weblogic上傳至/home/webl…

2分鐘快速實現非邏輯卷磁盤擴容

在虛擬機環境中&#xff0c;您可以擴展虛擬硬盤的大小而不影響數據。以下是擴展 /dev/sdb 磁盤從200G到500G并擴展 /dev/sdb1 分區到新大小的步驟&#xff1a; 關閉相關服務&#xff1a;確保沒有服務正在訪問 /app 分區。 關閉虛擬機&#xff1a;關閉您要更改磁盤大小的虛擬機…

「首屆廣州百家新銳企業」名單出爐!數說故事遴選入圍

11月20日&#xff0c;由中共廣州市委統戰部、市工商聯、市工信局、市國資委、市科技局聯合主辦的首屆廣州百家新銳企業融通創新交流會在廣州成功舉辦。 為推動廣州市中小民營企業的創新發展&#xff0c;踐行新發展理念&#xff0c;厚植廣州產業根基&#xff0c;現場發布首屆廣…

qt實現播放視屏的時候,加載外掛字幕(.srt文件解析)

之前用qt寫了一個在windows下播放視頻的軟件&#xff0c;具體介紹參見qt編寫的視頻播放器&#xff0c;windows下使用&#xff0c;精致小巧_GreenHandBruce的博客-CSDN博客 后來發現有些視頻沒有內嵌字幕&#xff0c;需要外掛字幕&#xff0c;這時候&#xff0c;我就想著把加載…

SELinux零知識學習二十六、SELinux策略語言之類型強制(11)

接前一篇文章:SELinux零知識學習二十五、SELinux策略語言之類型強制(10) 二、SELinux策略語言之類型強制 3. 訪問向量規則 AV規則就是按照對客體類別的訪問許可指定具體含義的規則,SELinux策略語言目前支持四類AV規則: allow:表示允許主體對客體執行允許的操作。nevera…