递归、搜索与回溯-FloodFill:33.太平洋大西洋水流问题

题目链接:417. 太平洋大西洋水流问题(中等)

算法原理:

解法:DFS

Java算法:

java 复制代码
import java.util.ArrayList;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 王洋
 * Date: 2025-10-09
 * Time: 22:26
 */
class Solution {
    //417. 太平洋大西洋水流问题
    //自己写的,不能用hash表的原因:有高度一样的,无法锁定坐标,其余一遍过
    //豆包帮我改出来的:要用两个boolean数组分别记录,否则第二个就记录不上了
    int m,n;
    int[] dx=new int[]{0,0,1,-1};
    int[] dy=new int[]{1,-1,0,0};
    List<List<Integer>> ret;
    List<Integer> tmp;
    boolean[][] vis1;//统计流向太平洋的
    boolean[][] vis2;//统计流向大西洋的
    //Map<Intger,Integer> hash;
    public List<List<Integer>> pacificAtlantic(int[][] heights) {
        ret=new ArrayList<>();
        //hash=new HashMap<>();
        m=heights.length;n=heights[0].length;
        vis1=new boolean[m][n];
        vis2=new boolean[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                //统计能流向太平洋的
                if(!vis1[i][j]&&(i==0||j==0)){
                    vis1[i][j]=true;
                    //记录当前值
                    int prev=heights[i][j];
                    dfs(heights,i,j,prev,vis1);
                }
                //统计能流向大西洋的
                if(!vis2[i][j]&&(i==m-1||j==n-1)){
                    vis2[i][j]=true;
                    //记录当前值
                    int prev=heights[i][j];
                    dfs(heights,i,j,prev,vis2);
                }
            }
        }
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(vis1[i][j]&&vis2[i][j]){
                    tmp=new ArrayList<>();//每次进入都要重新统计
                    tmp.add(i);
                    tmp.add(j);
                    ret.add(tmp);
                }
            }
        }
        // for(<Map.Entry<Integer,Integer> entry:entries){
        //     if(entry.getKey()>1){
        //         tmp=new ArrayList<>();//每次进入都要重新统计
        //         tmp.add(entry.getKey());
        //         tmp.add(entry.getValue());
        //         ret.add(tmp);
        //     }
        // }
        return ret;
    }
    public void dfs(int[][] heights,int i,int j,int prev,boolean[][] vised){
        for(int k=0;k<4;k++){
            int x=i+dx[k],y=j+dy[k];
            if(x<m&&y<n&&x>=0&&y>=0&&!vised[x][y]&&heights[x][y]>=prev){
                vised[x][y]=true;
                //hash.put(heights[x][y],hash.getOrDefalut(heights[x][y],0)+1);
                dfs(heights,x,y,heights[x][y],vised);
            }
        }
    }


    class Solution {
        //自己写的,不能用hash表的原因:有高度一样的,无法锁定坐标,其余一遍过
        //豆包帮我改出来的:要用两个boolean数组分别记录,否则第二个就记录不上了
        //吴小哲的跟我的差不多,主要不同点在标记方法上,他用n的复杂度,我用的n²的复杂度+dfs不用记录之前的数
        //直接height[x][y]跟height[i][j]比较就行
        int m,n;
        int[] dx=new int[]{0,0,1,-1};
        int[] dy=new int[]{1,-1,0,0};
        List<List<Integer>> ret;
        List<Integer> tmp;
        boolean[][] vis1;//统计流向太平洋的
        boolean[][] vis2;//统计流向大西洋的
        //Map<Intger,Integer> hash;
        public List<List<Integer>> pacificAtlantic(int[][] heights) {
            ret=new ArrayList<>();
            //hash=new HashMap<>();
            m=heights.length;n=heights[0].length;
            vis1=new boolean[m][n];
            vis2=new boolean[m][n];
            // for(int i=0;i<m;i++){
            //     for(int j=0;j<n;j++){
            //         //统计能流向太平洋的
            //         if(!vis1[i][j]&&(i==0||j==0)){
            //             vis1[i][j]=true;
            //             //记录当前值
            //             int prev=heights[i][j];
            //             dfs(heights,i,j,prev,vis1);
            //         }
            //         //统计能流向大西洋的
            //         if(!vis2[i][j]&&(i==m-1||j==n-1)){
            //             vis2[i][j]=true;
            //             //记录当前值
            //             int prev=heights[i][j];
            //             dfs(heights,i,j,prev,vis2);
            //         }
            //     }
            // }

            //吴小哲的标记方法,我感觉挺好的,直接时间复杂度n²降到n

            //流向太平洋的
            for(int i=0;i<m;i++){vis1[i][0]=true;dfs(heights,i,0,vis1);}
            for(int j=0;j<n;j++){vis1[0][j]=true;dfs(heights,0,j,vis1);}
            //流向大西洋的
            for(int i=0;i<m;i++){vis2[i][n-1]=true;dfs(heights,i,n-1,vis2);}
            for(int j=0;j<n;j++){vis2[m-1][j]=true;dfs(heights,m-1,j,vis2);}

            for(int i=0;i<m;i++){
                for(int j=0;j<n;j++){
                    if(vis1[i][j]&&vis2[i][j]){
                        tmp=new ArrayList<>();//每次进入都要重新统计
                        tmp.add(i);
                        tmp.add(j);
                        ret.add(tmp);
                    }
                }
            }
            // for(<Map.Entry<Integer,Integer> entry:entries){
            //     if(entry.getKey()>1){
            //         tmp=new ArrayList<>();//每次进入都要重新统计
            //         tmp.add(entry.getKey());
            //         tmp.add(entry.getValue());
            //         ret.add(tmp);
            //     }
            // }
            return ret;
        }
        public void dfs(int[][] heights,int i,int j,boolean[][] vised){
            for(int k=0;k<4;k++){
                int x=i+dx[k],y=j+dy[k];
                if(x<m&&y<n&&x>=0&&y>=0&&!vised[x][y]&&heights[x][y]>=heights[i][j]){
                    vised[x][y]=true;
                    //hash.put(heights[x][y],hash.getOrDefalut(heights[x][y],0)+1);
                    dfs(heights,x,y,vised);
                }
            }
        }
    }
}
相关推荐
尋有緣1 小时前
力扣1069-产品销售分析II
leetcode·oracle·数据库开发
l***37091 小时前
spring 跨域CORS Filter
java·后端·spring
CodeByV1 小时前
【算法题】双指针(二)
数据结构·算法
P***84391 小时前
idea创建springBoot的五种方式
java·spring boot·intellij-idea
yuanhello1 小时前
【Android】Android的键值对存储方案对比
android·java·android studio
2501_941142931 小时前
云原生微服务环境下服务熔断与降级优化实践——提升系统稳定性与容错能力
java·大数据·网络
2501_941404311 小时前
多云环境下微服务化AI大模型的企业部署与优化实践指南
java
浩瀚地学1 小时前
【Java】数组
java·开发语言