Leectcode417太平洋大西洋水流问题_med_C++

给定一个 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;
    }
};