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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

⭐算法入门⭐《广度优先搜索》中等01 —— LeetCode 994. 腐烂的橘子

發布時間:2024/8/1 编程问答 48 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ⭐算法入门⭐《广度优先搜索》中等01 —— LeetCode 994. 腐烂的橘子 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

🙉飯不食,水不飲,題必須刷🙉
C語言免費動漫教程,和我一起打卡! 🌞《光天化日學C語言》🌞
LeetCode 太難?先看簡單題! 🧡《C語言入門100例》🧡
數據結構難?不存在的! 🌳《數據結構入門》🌳
LeetCode 太簡單?算法學起來! 🌌《夜深人靜寫算法》🌌

文章目錄

  • 一、題目
    • 1、題目描述
    • 2、基礎框架
    • 3、原題鏈接
  • 二、解題報告
    • 1、思路分析
    • 2、時間復雜度
    • 3、代碼詳解
  • 三、本題小知識
  • 四、加群須知

一、題目

1、題目描述

在給定的網格中,每個單元格可以有以下三個值之一:
??1)值 0 代表空單元格;
??2)值 1 代表新鮮橘子;
??3)值 2 代表腐爛的橘子。
每分鐘,任何與腐爛的橘子(在 4 個正方向上)相鄰的新鮮橘子都會腐爛。返回直到單元格中沒有新鮮橘子為止所必須經過的最小分鐘數。如果不可能,返回 -1。

??樣例輸入:[211110011]\left[ \begin{matrix} 2 & 1 & 1 \\ 1 & 1 & 0 \\ 0 & 1 & 1\end{matrix} \right]???210?111?101????

??樣例輸出: 4

2、基礎框架

  • c++ 版本給出的基礎框架代碼如下:
class Solution { public:int orangesRotting(vector<vector<int>>& grid) {} };
  • vector<vector<int>>& grid代表的是一個二維數組,用來代表二維矩陣的橘子位置,&作為引用,用來加速參數傳遞。
  • 返回值是一個int,代表哪個時刻下所有橘子都腐爛了。

3、原題鏈接

LeetCode 994. 腐爛的橘子

二、解題報告

1、思路分析

??首先,將所有腐爛的橘子(值為 2 的格子)的位置進行哈希(標記訪問時間為 0),然后壓入隊列。利用廣搜,擴散范圍。對于相鄰的格子,如下幾種情況分別處理:
??1)格子沒有被訪問過,且遇到一個新鮮橘子(值為 1 的格子),哈希后壓入隊列,并且標記格子的訪問時間為相鄰那個擴散到它的格子的訪問時間 + 1。
??2)格子沒有被訪問過,且遇到空位置,不做任何處理;
??3)格子被訪問過,不做任何處理;
搜索完畢,遍歷所有格子,如果存在新鮮橘子,返回 -1;否則,取最訪問時間最大的進行返回。

  • 廣搜的更多內容,可以參考這篇文章:夜深人靜寫算法(十)- 單向廣搜。

2、時間復雜度

  • 對于一個 n×mn \times mn×m 的矩陣,每個元素只會訪問一次,時間復雜度為 O(nm)O(nm)O(nm)

3、代碼詳解

int dir[4][2] = {{0, 1}, // right{1, 0}, // down{0, -1}, // left{-1, 0}, // up };const int maxn = 120;class Solution {int n, m;int visited[maxn];queue <int> que;int getVisitedId(int x, int y) { // (1)return x * m + y;}void getPosByVisitedId(int visitedId, int &x, int &y) { // (2)x = visitedId / m;y = visitedId % m;}void init(vector<vector<int>>& mat) {while(!que.empty()) { // (3)que.pop();}memset(visited, -1, sizeof(visited)); // (4)n = mat.size(); // (5)m = mat[0].size(); // (6)for(int i = 0; i < n; ++i) {for(int j = 0; j < m; ++j) {if(2 == mat[i][j]) { // (7)visited[ getVisitedId(i, j) ] = 0; que.push( getVisitedId(i, j) );}}}}bool outOfBound(int x, int y) {return x < 0 || x >= n || y < 0 || y >= m; }void bfs(vector<vector<int>>& mat) {while(!que.empty()) {int vid = que.front(); // (8)int x, y;getPosByVisitedId(vid, x, y); // (9)que.pop();for(int i = 0; i < 4; ++i) { // (10)int tx = x + dir[i][0];int ty = y + dir[i][1];if(outOfBound(tx, ty)) {continue;}int nextvid = getVisitedId(tx, ty); // (11)if(mat[tx][ty] == 1 && visited[nextvid] == -1) { visited[nextvid] = visited[vid] + 1; que.push(nextvid);}}}}int output(int *visited, vector<vector<int>>& mat) { int maxv = 0;for(int i = 0; i < n; ++i) {vector <int> ans;for(int j = 0; j < m; ++j) {int vid = getVisitedId(i, j);if(mat[i][j] == 1 && visited[ vid ] == -1) { return -1; // (12)}if( visited[ vid ] > maxv ) {maxv = visited[ vid ]; // (13)}}}return maxv;} public:int orangesRotting(vector<vector<int>>& grid) {init(grid); bfs(grid);return output(visited, grid);} };
  • (1)(1)(1) 將二維向量映射到一維,方便索引;
  • (2)(2)(2) 將一維向量拆解成二維,方便計算;
  • (3)(3)(3) 定義的隊列為類私有成員,所以每次計算,初始化的時候需要首先進行清空;
  • (4)(4)(4) 利用memset初始化將所有矩陣元素的標記位全部置為-1,關于memset更多用法,可以參考:《C/C++ 面試 100 例》(六)memset 全網最全總結;
  • (5)(5)(5) 矩陣的行,保存成類的成員變量,方便成員函數使用;
  • (6)(6)(6) 矩陣的列,保存成類的成員變量,方便成員函數使用;
  • (7)(7)(7) 找到矩陣中所有的 2(腐爛的橘子),將標記為置為 0,代表腐爛的時刻為 0,然后塞入隊列;
  • (8)(8)(8) 每次從隊列頭部彈出一個元素;
  • (9)(9)(9) 將它轉換成坐標的形式,方便進行上下左右的運算;
  • (10)(10)(10) 枚舉四個方向擴散;
  • (11)(11)(11) 得到一個相鄰位置,如果這個位置沒有被訪問過,且值為 1 (代表新鮮橘子),則將步數置為 當前位置步數 + 1;
  • (12)(12)(12) 搜索完畢,遍歷所有格子,如果存在新鮮橘子,返回 -1;
  • (13)(13)(13) 否則,取最訪問時間最大的進行返回。

三、本題小知識

1)一維的vector可以當數組用,二維的vector可以當矩陣用。
2)利用memset可以將標記置為-1代表尚未訪問。
3)廣搜的過程,就是不斷把狀態壓入隊列尾,不斷取出隊列頭部狀態的過程,由于狀態可能是多維的,所以我們一般考慮將多維狀態變成一維,這個稱為序列化;再在彈出隊列的時候,將一維狀態還原成多維,這個稱為反序列化。一般就是通過進制轉換來完成。


四、加群須知

??相信看我文章的大多數都是「 大學生 」,能上大學的都是「 精英 」,那么我們自然要「 精益求精 」,如果你還是「 大一 」,那么太好了,你擁有大把時間,當然你可以選擇「 刷劇 」,然而,「 學好算法 」,三年后的你自然「 不能同日而語 」
??那么這里,我整理了「 幾十個基礎算法 」 的分類,點擊開啟:

🌌《算法入門指引》🌌
??如果鏈接被屏蔽,或者有權限問題,可以私聊作者解決。

??大致題集一覽:





??為了讓這件事情變得有趣,以及「 照顧初學者 」,目前題目只開放最簡單的算法 「 枚舉系列 」 (包括:線性枚舉、雙指針、前綴和、二分枚舉、三分枚舉),當有 一半成員刷完 「 枚舉系列 」 的所有題以后,會開放下個章節,等這套題全部刷完,你還在群里,那么你就會成為「 夜深人靜寫算法 」專家團 的一員。
??不要小看這個專家團,三年之后,你將會是別人 望塵莫及 的存在。如果要加入,可以聯系我,考慮到大家都是學生, 沒有「 主要經濟來源 」,在你成為神的路上,「 不會索取任何 」
??🔥聯系作者,或者掃作者主頁二維碼加群,加入刷題行列吧🔥


🔥讓天下沒有難學的算法🔥
C語言免費動漫教程,和我一起打卡! 🌞《光天化日學C語言》🌞
入門級C語言真題匯總 🧡《C語言入門100例》🧡
幾張動圖學會一種數據結構 🌳《畫解數據結構》🌳
組團學習,抱團生長 🌌《算法入門指引》🌌
競賽選手金典圖文教程 💜《夜深人靜寫算法》💜

總結

以上是生活随笔為你收集整理的⭐算法入门⭐《广度优先搜索》中等01 —— LeetCode 994. 腐烂的橘子的全部內容,希望文章能夠幫你解決所遇到的問題。

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