代碼隨想錄第五十二天| 101.孤島的總面積 102.沉沒孤島 103.水流問題 104.建造最大島嶼

孤島的總面積

題目描述

給定一個由 1(陸地)和 0(水)組成的矩陣,島嶼指的是由水平或垂直方向上相鄰的陸地單元格組成的區域,且完全被水域單元格包圍。孤島是那些位于矩陣內部、所有單元格都不接觸邊緣的島嶼。現在你需要計算所有孤島的總面積,島嶼面積的計算方式為組成島嶼的陸地的總數。

解題思路

  1. 標記邊緣島嶼:首先遍歷矩陣的邊緣,如果發現陸地(1),則使用深度優先搜索(DFS)標記整個島嶼,這些島嶼不是孤島。
  2. 計算孤島面積:再次遍歷矩陣,對于未被標記且是陸地的單元格,使用DFS計算其所在島嶼的面積,并將所有孤島的面積累加。

代碼實現

import java.util.*;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int m = sc.nextInt();int n = sc.nextInt();int[][] grid = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {grid[i][j] = sc.nextInt();}}boolean[][] visited = new boolean[m][n];// 標記邊緣島嶼for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && grid[i][j] == 1 && !visited[i][j]) {visited[i][j] = true;dfsMarkEdge(i, j, visited, grid);}}}int totalArea = 0;// 計算孤島總面積for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (!visited[i][j] && grid[i][j] == 1) {visited[i][j] = true;totalArea += dfsCalculateArea(i, j, visited, grid);}}}System.out.println(totalArea);  }private static final int[][] directions = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};// DFS標記邊緣島嶼public static void dfsMarkEdge(int x, int y, boolean[][] visited, int[][] grid) {for (int i = 0; i < 4; i++) {int nextX = x + directions[i][0];int nextY = y + directions[i][1];if (nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) continue;if (!visited[nextX][nextY] && grid[nextX][nextY] == 1) {visited[nextX][nextY] = true;dfsMarkEdge(nextX, nextY, visited, grid);}}}// DFS計算孤島面積public static int dfsCalculateArea(int x, int y, boolean[][] visited, int[][] grid) {int area = 1;for (int i = 0; i < 4; i++) {int nextX = x + directions[i][0];int nextY = y + directions[i][1];if (nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) continue;if (!visited[nextX][nextY] && grid[nextX][nextY] == 1) {visited[nextX][nextY] = true;area += dfsCalculateArea(nextX, nextY, visited, grid);}}return area;}
}

沉沒孤島

題目描述

給定一個由 1(陸地)和 0(水)組成的矩陣,島嶼指的是由水平或垂直方向上相鄰的陸地單元格組成的區域,且完全被水域單元格包圍。孤島是那些位于矩陣內部、所有單元格都不接觸邊緣的島嶼。現在你需要將所有孤島“沉沒”,即將孤島中的所有陸地單元格(1)轉變為水域單元格(0)。

解題思路

  1. 標記邊緣島嶼:首先遍歷矩陣的邊緣,如果發現陸地(1),則使用深度優先搜索(DFS)標記整個島嶼,這些島嶼不是孤島。
  2. 沉沒孤島:再次遍歷矩陣,對于未被標記且是陸地的單元格,將其置為0,從而實現沉沒孤島。

代碼實現

import java.util.*;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int m = sc.nextInt();int n = sc.nextInt();int[][] grid = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {grid[i][j] = sc.nextInt();}}boolean[][] visited = new boolean[m][n];// 標記邊緣島嶼for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if ((i == 0 || i == m - 1 || j == 0 || j == n - 1) && grid[i][j] == 1 && !visited[i][j]) {visited[i][j] = true;dfsMarkEdge(i, j, visited, grid);}}}// 沉沒孤島for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (!visited[i][j] && grid[i][j] == 1) {grid[i][j] = 0;}}}// 輸出結果矩陣for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {System.out.print(grid[i][j] + " ");}System.out.println();}sc.close(); }private static final int[][] directions = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};// DFS標記邊緣島嶼public static void dfsMarkEdge(int x, int y, boolean[][] visited, int[][] grid) {for (int i = 0; i < 4; i++) {int nextX = x + directions[i][0];int nextY = y + directions[i][1];if (nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) continue;if (!visited[nextX][nextY] && grid[nextX][nextY] == 1) {visited[nextX][nextY] = true;dfsMarkEdge(nextX, nextY, visited, grid);}}}
}

水流問題

題目描述

現有一個 N × M 的矩陣,每個單元格包含一個數值,這個數值代表該位置的相對高度。矩陣的左邊界和上邊界被認為是第一組邊界(太平洋),而矩陣的右邊界和下邊界被視為第二組邊界(大西洋)。當雨水落在上面時,水會根據地形的傾斜向低處流動,但只能從較高或等高的地點流向較低或等高并且相鄰(上下左右方向)的地點。我們的目標是確定那些單元格,從這些單元格出發的水可以達到第一組邊界和第二組邊界。

解題思路

  1. 雙邊界標記:分別從太平洋和大西洋的邊界出發,使用深度優先搜索(DFS)標記所有能夠流向對應邊界的單元格。
    • 對于太平洋,遍歷矩陣的左邊界和上邊界,從這些邊界上的每個單元格開始 DFS,標記所有能流向太平洋的單元格。
    • 對于大西洋,遍歷矩陣的右邊界和下邊界,從這些邊界上的每個單元格開始 DFS,標記所有能流向大西洋的單元格。
  2. 結果收集:遍歷整個矩陣,找出同時被太平洋和大西洋標記的單元格,這些單元格即為所求。

代碼實現

import java.util.*;public class Main {public static void main(String[] args) {Scanner sc = new Scanner(System.in);int m = sc.nextInt();int n = sc.nextInt();int[][] grid = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {grid[i][j] = sc.nextInt();}}// 初始化兩個二維 boolean 數組,分別代表能流向太平洋和大西洋的單元格boolean[][] pacific = new boolean[m][n];boolean[][] atlantic = new boolean[m][n];// 從太平洋邊界出發進行 DFSfor (int i = 0; i < m; i++) {dfs(i, 0, pacific, grid, Integer.MIN_VALUE);}for (int j = 0; j < n; j++) {dfs(0, j, pacific, grid, Integer.MIN_VALUE);}// 從大西洋邊界出發進行 DFSfor (int i = 0; i < m; i++) {dfs(i, n - 1, atlantic, grid, Integer.MIN_VALUE);}for (int j = 0; j < n; j++) {dfs(m - 1, j, atlantic, grid, Integer.MIN_VALUE);}// 收集結果List<List<Integer>> res = new ArrayList<>();for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (pacific[i][j] && atlantic[i][j]) {res.add(Arrays.asList(i, j));}}}// 輸出結果for (List<Integer> list : res) {for (int k = 0; k < list.size(); k++) {if (k == 0) {System.out.print(list.get(k) + " ");} else {System.out.print(list.get(k));}}System.out.println();}sc.close(); }// DFS 函數,用于標記能流向指定邊界的所有單元格public static void dfs(int x, int y, boolean[][] valid, int[][] grid, int preH) {if (x < 0 || y < 0 || x >= grid.length || y >= grid[0].length || valid[x][y]) return;if (grid[x][y] < preH) return;valid[x][y] = true;dfs(x + 1, y, valid, grid, grid[x][y]);dfs(x - 1, y, valid, grid, grid[x][y]);dfs(x, y + 1, valid, grid, grid[x][y]);dfs(x, y - 1, valid, grid, grid[x][y]);}
}

建造最大島嶼

題目描述

給定一個由 1(陸地)和 0(水)組成的矩陣,你最多可以將矩陣中的一格水變為一塊陸地,在執行了此操作之后,矩陣中最大的島嶼面積是多少。島嶼面積的計算方式為組成島嶼的陸地的總數。島嶼是被水包圍,并且通過水平方向或垂直方向上相鄰的陸地連接而成的。你可以假設矩陣外均被水包圍。

解題思路

  1. 預處理島嶼:首先遍歷整個矩陣,使用深度優先搜索(DFS)標記每個島嶼,并記錄每個島嶼的面積。
  2. 模擬填海:對于每個水域單元格,模擬將其變為陸地,然后檢查其上下左右相鄰的島嶼,計算這些島嶼合并后的總面積(包括當前填海的單元格)。
  3. 結果計算:在所有可能的填海位置中,找到最大的島嶼面積。

代碼實現

import java.util.*;
import java.math.*;public class Main {private static final int[][] dir = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};public static void main(String[] args) {Scanner sc = new Scanner(System.in);int m = sc.nextInt();int n = sc.nextInt();int[][] grid = new int[m][n];for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {grid[i][j] = sc.nextInt();}}boolean[][] visited = new boolean[m][n];int mapnum = 1;int size = 0;HashMap<Integer, Integer> sizeMap = new HashMap<>();boolean isAllIsland = true;// 預處理所有島嶼for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == 0) isAllIsland = false;if (!visited[i][j] && grid[i][j] == 1) {visited[i][j] = true;grid[i][j] = mapnum;size = dfs(i, j, visited, grid, mapnum);sizeMap.put(mapnum, size);mapnum++;}}}int result = 0;HashSet<Integer> adjacentIslands = new HashSet<>();// 如果整個矩陣都是島嶼if (isAllIsland) {result = m * n;} else {// 遍歷每個水域單元格,模擬填海for (int i = 0; i < m; i++) {for (int j = 0; j < n; j++) {if (grid[i][j] == 0) {adjacentIslands.clear();int currentSize = 1; // 當前填海的單元格本身算1for (int z = 0; z < 4; z++) {int nextX = i + dir[z][0];int nextY = j + dir[z][1];if (nextX < 0 || nextY < 0 || nextX >= m || nextY >= n) continue;int neighborMark = grid[nextX][nextY];if (adjacentIslands.contains(neighborMark) || !sizeMap.containsKey(neighborMark)) continue;adjacentIslands.add(neighborMark);currentSize += sizeMap.get(neighborMark);}result = Math.max(currentSize, result);}}}}System.out.println(result);}// DFS 計算島嶼面積并標記public static int dfs(int x, int y, boolean[][] visited, int[][] grid, int mapnum) {int size = 1;for (int i = 0; i < 4; i++) {int nextX = x + dir[i][0];int nextY = y + dir[i][1];if (nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length) continue;if (!visited[nextX][nextY] && grid[nextX][nextY] == 1) {visited[nextX][nextY] = true;grid[nextX][nextY] = mapnum;size += dfs(nextX, nextY, visited, grid, mapnum);}}return size;}
}

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

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

相關文章

八叉樹地圖的原理與實現

八叉樹與體素圖 八叉樹地圖 八叉樹地圖是可變分辨率的三維柵格地圖&#xff0c;可以自由調整分辨率&#xff0c;如下所示&#xff1a; 根據點云的數量或密度決定每個葉子方塊是否被占據 體素圖 體素就是固定分辨率的三維柵格地圖&#xff0c;如下所示&#xff1a; 根據點云…

最節省服務器,手搓電子證書查詢系統

用戶預算150元&#xff0c;想要一個最簡單證書查詢系統。前臺能查詢證書、后臺管理員能登錄能修改密碼&#xff0c;證書能夠手動輸入修改刪除、批量導入導出刪除數據、查詢搜索。能夠兼容蘋果、安卓、PC三端瀏覽器&#xff0c;最后幫忙部署到云服務器上。 用戶預算不多&#xf…

什么是全棧?

&#x1f91f;致敬讀者 &#x1f7e9;感謝閱讀&#x1f7e6;笑口常開&#x1f7ea;生日快樂?早點下班 &#x1f4d8;博主相關 &#x1f7e7;博主信息&#x1f7e8;博客首頁&#x1f7eb;專欄推薦&#x1f7e5;活動信息 &#x1f4c3;文章前言 &#x1f537;文章均為學習工…

作物移栽機器人的結構設計的介紹

作物移栽機器人的結構設計是一個復雜的機械與電子結合的系統工程&#xff0c;單純用代碼來實現整個結構設計是不現實的&#xff0c;因為結構設計更多涉及到機械結構、硬件選型等物理層面的內容。不過&#xff0c;我們可以通過代碼來模擬作物移栽機器人的部分功能&#xff0c;例…

【文獻閱讀】SPRec:用自我博弈打破大語言模型推薦的“同質化”困境

&#x1f4dc;研究背景 在如今的信息洪流中&#xff0c;推薦系統已經成為了我們生活中的“貼心小助手”&#xff0c;無論是看電影、聽音樂還是購物&#xff0c;推薦系統都在努力為我們提供個性化的內容。但這些看似貼心的推薦背后&#xff0c;其實隱藏著一個嚴重的問題——同質…

使用1Panel一鍵搭建WordPress網站的詳細教程(全)

嘿&#xff0c;各位想搭建自己網站的朋友們&#xff01;今天我要跟大家分享我用1Panel搭建WordPress網站的全過程。說實話&#xff0c;我之前對服務器運維一竅不通&#xff0c;但通過這次嘗試&#xff0c;我發現原來建站可以這么簡單&#xff01;下面是我的親身經歷和一些小技巧…

本地fake server,

C# 制作的系統級tcp 重定向&#xff0c;整個系統只要有訪問指定url&#xff0c;返回自定義內容到訪問端。不局限在瀏覽器單一方面。 再者請理解這個圖的含金量&#xff0c;服務器down機都可以模擬。 用途那就太多了&#xff0c;當然很多用途都不正當。嘿嘿 如果你很想要源代…

設計模式之美

UML建模 統一建模語言&#xff08;UML&#xff09;是用來設計軟件的可視化建模語言。它的語言特點是簡單 統一 圖形化 能表達軟件設計中的動態與靜態信息。 UML的分類 動態結構圖&#xff1a; 類圖 對象圖 組件圖 部署圖 動態行為圖&#xff1a; 狀態圖 活動圖 時序圖 協作…

【openGauss】物理備份恢復

文章目錄 1. gs_backup&#xff08;1&#xff09;備份&#xff08;2&#xff09;恢復&#xff08;3&#xff09;手動恢復的辦法 2. gs_basebackup&#xff08;1&#xff09;備份&#xff08;2&#xff09;恢復① 偽造數據目錄丟失② 恢復 3. gs_probackup&#xff08;1&#xf…

一文了解JVM的垃圾回收

Java堆內存結構 java堆內存是垃圾回收器管理的主要區域&#xff0c;也被稱為GC堆。 為了方便垃圾回收&#xff0c;堆內存被分為新生代、老年代和永久代。 新創建的對象的內存會在新生代中分配&#xff0c;達到一定存活時長后會移入老年代&#xff0c;而永久代存儲的是類的元數…

SQL子查詢與MyBatis映射

文章目錄 前言1. 數據庫表結構2. MyBatis Mapper XML3. Java 實體類4. 技術點解析5. 執行效果6. 優化建議 前言 提示&#xff1a;這里可以添加本文要記錄的大概內容&#xff1a; 以下是一個結合 SQL 別名、子查詢、MyBatis 字段映射和代碼復用的完整案例&#xff0c;以用戶管…

基于SpringBoot的“校園周邊美食探索及分享平臺”的設計與實現(源碼+數據庫+文檔+PPT)

基于SpringBoot的“校園周邊美食探索及分享平臺”的設計與實現&#xff08;源碼數據庫文檔PPT) 開發語言&#xff1a;Java 數據庫&#xff1a;MySQL 技術&#xff1a;SpringBoot 工具&#xff1a;IDEA/Ecilpse、Navicat、Maven 系統展示 校園周邊美食探索及分享平臺結構圖…

時間復雜度(Time Complexity)

時間復雜度 1. 什么是時間復雜度&#xff1f; 時間復雜度&#xff08;Time Complexity&#xff09;是計算算法執行時間隨輸入規模&#xff08;n&#xff09;增長的變化趨勢。它衡量算法的效率&#xff0c;通常使用大 O 記號&#xff08;Big-O notation&#xff09;表示&#…

樹莓派:更新源

發行版本 Debian 一直維護著至少三個發行版本&#xff1a;“穩定版&#xff08;stable&#xff09;”&#xff0c;“測試版&#xff08;testing&#xff09;”和“不穩定版&#xff08;unstable&#xff09;”。 發行版目錄 下一代 Debian 正式發行版的代號為 bullseye — 發布…

K8s 1.27.1 實戰系列(八)Service

一、Service介紹 1、Service 的作用與核心功能 Service 是 Kubernetes 中用于抽象一組 Pod 并提供穩定訪問入口的資源。它解決了以下問題: ?Pod IP 不固定:Pod 可能因故障、擴縮容或更新導致 IP 變化,Service 通過 ClusterIP(虛擬 IP)提供固定訪問地址。?負載均衡:自動…

RocketMQ性能優化篇

在分布式消息系統中&#xff0c;RocketMQ以其高性能、高可靠性和高可擴展性而被廣泛應用。然而&#xff0c;為了充分發揮其性能優勢&#xff0c;需要進行一系列的性能測試和優化。本文將從性能測試方法和優化實踐兩個方面&#xff0c;詳細介紹如何對RocketMQ進行性能優化。通過…

CSS 知識點總結1

CSS 知識點總結&#xff11; 今天寫了兩個頁面,用到的知識點,總結一下 1. Flexbox 布局 display: flex;&#xff1a;啟用 Flexbox 布局&#xff0c;用于創建靈活的容器。flex-direction: column;&#xff1a;將子元素垂直排列。justify-content&#xff1a;控制子元素在主軸…

雙指針算法專題之——復寫零

文章目錄 題目介紹思路分析異地復寫優化為就地復寫 AC代碼 題目介紹 鏈接: 1089. 復寫零 思路分析 那么這道題我們依然可以使用雙指針算法來解決 異地復寫 先不考慮題目的要求&#xff0c;直接就地在原數組上修改&#xff0c;可能不太好想&#xff0c;我們這里可以先在一個…

Python控制語句 ——break和continue

1.以下關于Python循環結構的描述中,錯誤的是() 。 A、break用來結束當前當次語句,但不跳出當前的循環體。 B、遍歷循環中的遍歷結構可以是字符串、文件、組合數據類型和range函數等。 C、Python通過for,while等保留字構建循環結構。 D、continue只結束本次循環。 答案:A。在…

搭建阿里云專有網絡VPC

目錄 一、概述 二、專有網絡vpc 2.1 vpc基本信息 2.2 vpc資源管理 2.3 vpc網段管理 三、交換機 四、NAT網關 4.1 綁定彈性公網IP 4.2 NAT網關信息 4.3 綁定的彈性公網IP 4.4 DNAT 4.5 SNAT 五、彈性公網IP 六、訪問控制ACL&#xff08;綁定交換機&#xff09; 6…