原题链接:
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>
对象,但它们之间有一些区别:
-
使用
ArrayList
创建新列表:List<Integer> newList = new ArrayList<>(); newList.add(1); newList.add(2); result.add(newList);
这种方法使用
ArrayList
类来创建新的列表,然后逐个添加元素。这样可以随时向newList
中添加或删除元素,并且允许元素重复。 -
使用
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));