1. 程式人生 > 實用技巧 >深度優先搜尋:水域大小

深度優先搜尋:水域大小

問題:你有一個用於表示一片土地的整形矩陣land,該矩陣中每個點的值代表對應地點的海拔高度。若值為0則表示水域。

   由垂直、水平或對角線相連的水域為池塘。池塘的大小是指相連線的水域的個數。編寫一個方法來計算矩陣中所有

   池塘的大小,返回值需要從小到大排序。

示例:

輸入:
[
  [0, 2,  1,  0],   
  [0, 1,  0,  1],
  [1, 1,  0,  1],
  [0, 1,  0,  1]
]
輸出:
  [1,  2,  4]

(隱藏提示1:如果給你一個指代水的單元格的行和列,你如何找到所有相鄰的水域?)

(隱藏提示2:嘗試使用遞迴計算含水單元格的數量)

(隱藏提示3:你如何確保不會再一次訪問相同的單元格?你可以思考一下深度優先搜尋如何在圖上工作)

用C++解決如上問題:

class Solution{
public:
   vector<int> pnndSizes(vector<vecotr<int>> &land)
  {   vector
<int> res; for(int i = 0; i < land.size(); i++) { for(int j = 0; j < land[i].size(); j++) { int count = 0;
if(land[i][j] == 0) { dfs(i, j, land, count); //進行一次有效的dfs if(count != 0) //如果搜尋結果不為0,則進行一次有效的計數 res.push_back(count); } } } sort(res.begin(), res.end()); //對容器中已計數的count進行大小排序 return res; }   
void dfs(int x, int y, vector<vector<int>> &land, int count) { land[x][y] = -1//對水域染色 count++; ind dx[8] = {0,1,1,1,0,-1,-1,-1}, dy[8] = {1,1,0,-1,-1,-1,0,1}; //以原點為基準的8個方向陣列 for(int i = 0; i < 8; i++) { int x1 = dx[i] + x; int y1 = dy[i] + y; if(x1 >=0 && x1 < land.size() && y1 >= 0 && y1 < land[0].size() && land[x][y] == 0) //在8個方向內且是水塘 dfs(x1, y1, land, count); //繼續深度搜索 } } };