class Solution {
    int row;
    int col;
    int [][]dir={
  {0,1},{0,-1},{-1,0},{0,1}};//对应坐标上下左右
    Set<String> pacificVisited=new HashSet<>();//左边太平洋去重
    Set<String> atlanticVisited=new HashSet<>();
    int [][]matrix;
    int [][]heights;

    public List<List<Integer>> pacificAtlantic(int[][] heights) {
     row=heights.length;
     col=row==0?0:heights[0].length;
    matrix=new int [row][col];//得到的是当前数组的具体数字
    this.heights=heights;

     //在两个海洋边缘开始遍历
     for(int i=0;i<row;i++){
         //流向左边海+10,右边+100
         dfs(i,0,10);//最左边第一排遍历
         dfs(i,col-1,100);//最右边第一排遍历
     }

     for(int j=0;j<col;j++){
         dfs(0,j,10);//最上边第一排遍历
         dfs(row-1,j,100);//最下边第一排遍历
     }

     List<List<Integer>>res=new ArrayList<>();
     for(int i=0;i<row;i++){
         for(int j=0;j<col;j++){
             if(matrix[i][j]==110){
                 res.add(List.of(i,j));
             }
         }
         return res;
     }

    }
  private void dfs(int i,int j,int offset){//offset是用来判断是否访问过
      if(!isInRange(i,j))//判断不在岛上就return
      return;

      String symbol=i+"@"+j;//作为标志,用来判断是否被访问过
      if(contains(symbol,offset)){//offset用于区分左右海?
             return;//存在就直接返回,就是访问过了就不访问了,return

      //接下来进入循环,联通
      matrix[i][j]+=offset;//如果连通就加起来得到110
      add(symbol,offset);

      for(int k=0;k<4;K++){//找到新的探索方向
        int newX=i+dir[k][0];
        int newY=j+dir[k][1];

        if(isInRange(newX,newY)&&heights[newX][newY]>=heights[i][j]){//就联通性成立,高到底
             String sym=newX+"@"+newY;
             if(contains(sym,offset))//判断是否访问过
             continue;

             dfs(newX,newY,offset);//再次遍历
        }
      }

      }
  }

  //添加到海洋
  private void add(String symbol,int offset){
      if(offset==10){//在左边海,就添加到HashSet里面
          pacificVisited.add(symbol);

      }else{
          atlanticVisited.add(symbol);
      }
  }


        //通过不同的索引知道在哪个海洋包含
    private boolean contains(String symbol,int offset){
        if(offset==10){//通过不同的索引知道在哪个海洋包含
            return pacificVisited.contains(symbol);
        }else{
            return atlanticVisited.contains(symbol);
        }
    }



    private boolean isInRange(int i,int j){//判断是否在边界的条件
    return i>=0&&j>=0&&i<row&&j<col;
    }
}