Leetcode題解系列——Max Area of Island(c++版)
阿新 • • 發佈:2018-12-13
題目大意:給出一個n*m的01矩陣,在矩陣中找出連續1所佔據的最大面積。連續指的是一個單位的上下左右必須有一個為1.
注意點:
- 矩陣不一定是方陣,在判斷長度時候要注意長和寬。
- 要注意搜尋時候出現越界的情況,要判斷座標是否合理。
- 利用深度搜索時候,可以不用visited陣列來判斷是否已經搜尋,可以通過改變矩陣中的值來確定。
一.演算法設計
顯然,這是一道深度搜索圖的問題,我們可以通過對於圖中為1的結點作為起點來進行搜尋,通過上下左右四個方向來查詢是否存在1,若存在1則繼續深度搜索,直到找不到任何一個1,返回遍歷的個數,即sum值。
判斷上下左右結點是否為1,我先初始化一個數組來生成四個方向的向量,每一個結點來分別進行四次遍歷,注意是否越界。另外,當找不到1的時候要記得減回去新加的向量,回到最初的起點。
二.程式碼實現
class Solution {
public:
int dir[4][2] = {{0,1},{1,0},{0,-1},{-1,0}};
int maxAreaOfIsland(vector<vector<int>>& grid) {
int result = 0;
for (int i = 0; i < grid.size(); ++i)
{
for (int j = 0; j < grid[0].size(); ++j)
{
if(grid[i][j] == 1){
int temp = dfs(i, j, grid);
result = max(result, temp);
}
}
}
return result;
}
int dfs(int x, int y, vector<vector<int>>& grid){
int sum = 1;
grid[x][y] = 2;
for (int i = 0; i < 4; ++i)
{
cout << "first:" << x << " " << y << endl;
x += dir[i][0];
y += dir[i][1];
if(x < 0 || y < 0 || x >= grid.size() || y >= grid[0].size()){
x -= dir[i][0];
y -= dir[i][1];
continue;
}
cout << x << " " << y << endl;
if(grid[x][y] == 1){
grid[x][y] = 2;
sum += dfs(x,y,grid);
cout << x << " " << y << " " << sum << endl;
}
x -= dir[i][0];
y -= dir[i][1];
}
return sum;
}
};
三.改進方法
以上我的演算法跑了96ms,連名次都沒有真是丟人。於是,我開始對於程式碼開始優化。既然我要訪問四個方向的結點,那就不必來回的加減向量,而是直接進行遞迴。
class Solution {
public:
int dfs(vector<vector<int>>& grid, int x, int y){
if (x < 0 || y < 0 || x >= grid.size() || y >= grid[0].size())
return 0;
if (grid[x][y] == 1){
grid[x][y] = 2;
return (1 + dfs(grid, x-1, y) + dfs(grid, x, y+1) + dfs(grid, x, y-1) + dfs(grid, x+1, y));
}else
return 0;
}
int maxAreaOfIsland(vector<vector<int>>& grid) {
int maxArea = 0;
for(int i=0; i < grid.size(); ++i)
for (int j=0; j < grid[0].size(); ++j){
// check if 1 is met, if yes, dfs and count the area
if (grid[i][j] == 1)
{
// we will set those visited 1 as 2, so that we dont need to store a vector<bool> visited
int area = dfs(grid, i, j);
if (area > maxArea) maxArea = area;
}
}
return maxArea;
}
};