給定一個 m x n 的非負整數矩陣來表示一片大陸上各個單元格的高度。“太平洋”處於大陸的左邊界和上邊界,而“大西洋”處於大陸的右邊界和下邊界。
規定水流只能按照上、下、左、右四個方向流動,且只能從高到低或者在同等高度上流動。
請找出那些水流既可以流動到“太平洋”,又能流動到“大西洋”的陸地單元的座標。
提示:
輸出座標的順序不重要
m 和 n 都小於150
示例:
給定下面的 5x5 矩陣:
太平洋 ~ ~ ~ ~ ~
~ 1 2 2 3 (5) *
~ 3 2 3 (4) (4) *
~ 2 4 (5) 3 1 *
~ (6) (7) 1 4 5 *
~ (5) 1 1 2 4 *
* * * * * 大西洋
返回:
[[0, 4], [1, 3], [1, 4], [2, 2], [3, 0], [3, 1], [4, 0]] (上圖中帶括號的單元).
思路:按照DFS的想法,從可以達到的邊上的點主詞進行深度優先搜索。取交集。
第一版按照之前的DFS的想法寫出的思路如下,發現堆棧會溢出。通過cout打印可以看出,出現了在兩個點循環調準的情況。如下圖所示
class Solution {
int d[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
bool IfValid(const vector<vector<int>>& matrix, int x, int y)
{
if( x<0 || x>=matrix.size() || y<0 || y>=matrix[0].size())
{
return false;
}
return true;
}
void DFS(const vector<vector<int>>& matrix,const int x,const int y,vector<vector<bool>>& res)
{
res[x][y] = true;
for(int i=0;i<4;i++)
{
int newx = x+d[i][0];
int newy = y+ d[i][1];
if(IfValid(matrix,newx,newy) && matrix[newx][newy] >= matrix[x][y])
{
cout<<"newx="<<newx<<"newy="<<newy<<endl;
DFS(matrix,newx,newy,res);
}
}
return;
}
public:
vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) {
vector<vector<int>> positionResult;
int height = matrix.size();
if(height == 0) return positionResult;
int length = matrix[0].size();
vector<vector<bool>> toTai(height,vector<bool>(length,false));
vector<vector<bool>> toDa(height,vector<bool>(length,false));
//利用DFS的方式從邊上開始遍歷完成
for( int i=0;i<height;i++)
{
DFS(matrix,i,0, toTai);
DFS(matrix,i,length-1,toDa);
}
for(int i=0; i<length;i++)
{
DFS(matrix,0,i,toTai);
DFS(matrix,height-1,i,toDa);
}
//去交集
for(int i=0; i<height; i++)
{
for(int j=0; j<length; j++)
{
if(toDa[i][j] && toTai[i][j])
{
vector<int> one;
one.push_back(i);
one.push_back(j);
positionResult.push_back(one);
}
}
}
return positionResult;
}
};
這裏仔細看是出現了無限遞歸,原因是res的結果只做了複製而沒做使用。因此需要在遞歸前的判斷加一個對res是否爲true的判斷,如果是true的話就代表搜索檢查過了,則不再檢查。
class Solution {
int d[4][2] = {{0,1},{0,-1},{-1,0},{1,0}};
bool IfValid(const vector<vector<int>>& matrix, int x, int y)
{
if( x<0 || x>=matrix.size() || y<0 || y>=matrix[0].size())
{
return false;
}
return true;
}
void DFS(const vector<vector<int>>& matrix,const int x,const int y,vector<vector<bool>>& res)
{
res[x][y] = true;
for(int i=0;i<4;i++)
{
int newx = x+d[i][0];
int newy = y+ d[i][1];
if(IfValid(matrix,newx,newy) && matrix[newx][newy] >= matrix[x][y] && !res[newx][newy])
{
cout<<"newx="<<newx<<"newy="<<newy<<endl;
DFS(matrix,newx,newy,res);
}
}
return;
}
public:
vector<vector<int>> pacificAtlantic(vector<vector<int>>& matrix) {
vector<vector<int>> positionResult;
int height = matrix.size();
if(height == 0) return positionResult;
int length = matrix[0].size();
vector<vector<bool>> toTai(height,vector<bool>(length,false));
vector<vector<bool>> toDa(height,vector<bool>(length,false));
//利用DFS的方式從邊上開始遍歷完成
for( int i=0;i<height;i++)
{
DFS(matrix,i,0, toTai);
DFS(matrix,i,length-1,toDa);
}
for(int i=0; i<length;i++)
{
DFS(matrix,0,i,toTai);
DFS(matrix,height-1,i,toDa);
}
//去交集
for(int i=0; i<height; i++)
{
for(int j=0; j<length; j++)
{
if(toDa[i][j] && toTai[i][j])
{
vector<int> one;
one.push_back(i);
one.push_back(j);
positionResult.push_back(one);
}
}
}
return positionResult;
}
};