417. Pacific Atlantic Water Flow

原题链接:

417. Pacific Atlantic Water Flow
https://leetcode.cn/problems/pacific-atlantic-water-flow/description/

完成情况:

解题思路:

在这里插入图片描述

题目表达有点问题,

Return a 2D list of grid coordinates result where result[i] = [ri, ci]
denotes that rain water can flow from cell (ri, ci) to both the
Pacific and Atlantic oceans.

但其实就是很直接的 2D list ,每一个都存储一个同时可以流向两个不同海洋的山坡的水。

这段代码是一个解决LeetCode上"太平洋大西洋水流问题"的解决方案。代码中使用了深度优先搜索(DFS)来解决问题。

首先,定义了一个Solution类,其中包含了一个position数组,用来表示四个方向的偏移量。然后定义了dfs方法,该方法用来进行深度优先搜索,以确定一个位置是否可以到达太平洋或大西洋。接着,定义了pacificAtlantic方法,该方法用来寻找可以同时到达太平洋和大西洋的位置。

在pacificAtlantic方法中,首先初始化了一个三维布尔数组visited,用来记录每个位置是否可以到达太平洋或大西洋。然后通过两个嵌套的for循环,分别对每一行和每一列进行深度优先搜索,标记可以到达太平洋和大西洋的位置。最后,再次遍历整个二维数组,找出既可以到达太平洋又可以到达大西洋的位置,并将其添加到结果数组中。

这段代码的主要目的是找出可以同时到达太平洋和大西洋的位置,并将这些位置添加到结果数组中。

参考代码:

package 代码随想录.图论;

import java.util.ArrayList;
import java.util.List;

public class _417太平洋大西洋水流问题_dfs {
    int position[][] = {
            {1,0},
            {-1,0},
            {0,1},
            {0,-1}
    };
    /**
     * 还是从上往下,从左往右的遍历,看看有几个能超出边界的
     * @param heights
     * @return
     */
    public List<List<Integer>> pacificAtlantic(int[][] heights) {
        int rowSize = heights.length,columnSize = heights[0].length;
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        //除了正常的row,col,还要再记录流到哪条洋(太平洋-1 还是 大西洋-0)看看是否都能流向
        boolean [][][] visited = new boolean[rowSize][columnSize][2];
        for (int row = 0;row < rowSize;row++){
            visited[row][columnSize - 1][0] = true;
            visited[row][0][1] = true;
            dfs_pacificAtlantic(heights, row, columnSize-1,0,visited);
            dfs_pacificAtlantic(heights,row,0,1,visited);
        }
        for (int column = 0;column < columnSize;column++){
            visited[rowSize - 1][column][0] = true;
            visited[0][column][1] = true;
            dfs_pacificAtlantic(heights,rowSize - 1,column,0,visited);
            dfs_pacificAtlantic(heights,0,column,1,visited);
        }
        //-----------------------------------------------------------剩余部分就是可以同时的
        for (int row = 0;row <rowSize;row++){
            for (int col = 0;col < columnSize;col++){
                if (visited[row][col][0] && visited[row][col][1]){
                    List<Integer> newList = new ArrayList<>();
                    newList.add(1);
                    newList.add(2);
                    result.add(newList);
                }
            }
        }
        return result;
    }

    private void dfs_pacificAtlantic(int[][] heights, int row, int col, int signedOcean, boolean[][][] visited) {
        for (int [] current : position){
            int curRow = current[0] + row ,curCol = col + current[1];
            //防止越界
            if (curRow < 0 || curRow >= heights.length || curCol < 0 || curCol >= heights[0].length)    continue;
            //剔除掉高度不满足的,或者是已经被访问过的
            if (heights[curRow][curCol] < heights[row][col] || visited[curRow][curCol][signedOcean])    continue;
            //--------------------------------------------------------------
            visited[curRow][curCol][signedOcean] = true;
            dfs_pacificAtlantic(heights,curRow,curCol,signedOcean,visited);
        }
    }
}

错误经验吸取

在这里插入图片描述
这两种方法都可以向 result 中添加一个新的 List<Integer> 对象,但它们之间有一些区别:

  1. 使用 ArrayList 创建新列表:

    List<Integer> newList = new ArrayList<>();
    newList.add(1);
    newList.add(2);
    result.add(newList);
    

    这种方法使用 ArrayList 类来创建新的列表,然后逐个添加元素。这样可以随时向 newList 中添加或删除元素,并且允许元素重复。

  2. 使用 List.of 创建不可变列表:

    result.add(List.of(row, col));
    

    这种方法使用 List.of 工厂方法来创建一个不可变列表。不可变列表意味着无法修改其内容,因此不能向其中添加或删除元素。此外,由于是不可变列表,它不允许重复元素。

因此,选择哪种方法取决于你的需求。如果需要在后续操作中修改列表内容或者需要允许重复元素,可以使用第一种方法;如果希望确保列表内容不可变,可以使用第二种方法。

在这里插入图片描述

在这里插入图片描述

//                    List<Integer> newList = new ArrayList<>();
//                    newList.add(1);
//                    newList.add(2);
//                    result.add(newList);
                    result.add(List.of(row,col));
  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值