1.装水问题
有一个 异形 容器,用一个 n * n 的二维数组来表示。其中 1 表示容器实心部分, 0 表示空心部分。现使用此容器装水,能装多少水(每个元素都表示一份水,只有有挡板的部分能装水)?
public class Work1001 {
public static void main(String[] args) {
int[][] arr = {
{0, 0, 1, 0, 0, 0, 0},
{0, 0, 1, 0, 0, 0, 0},
{0, 0, 1, 0, 1, 0, 0},
{1, 0, 1, 0, 1, 0, 1},
{1, 1, 1, 1, 1, 1, 1},
};
int sum = 0;
for (int i = 0; i < arr.length; i++) {
int count = 0;
int v = 0;
for (int j = 0; j < arr[0].length; j++) {
if (arr[i][j] == 1) {
count++;
if (count == 2) {
count = 1;
sum += v;
v = 0;
}
} else {
if (count > 0) {
v++;
}
}
}
}
System.out.println(sum);
}
}
思考:若是使用一个一维数组来表示实心部分高度该如何计算?(int[] arr = {2, 5, 1, 2, 3, 4, 7, 2}; )
import java.util.Arrays;
public class Work10012 {
public static void main(String[] args) {
int[] arr = {2, 5, 1, 2, 3, 4, 7, 2};
int len = Arrays.stream(arr).max().orElse(0);
// 定义二维数组
int[][] arr1 = new int[len][arr.length];
// 将一维数组转为二维数组
for (int i = len - 1; i >= 0; i--) {
for (int j = 0; j < arr.length; j++) {
if (arr[j] > 0) {
arr1[i][j] = 1;
arr[j]--;
}
}
}
// 计算能装多少水
int sum = 0;
for (int i = 0; i < arr1.length; i++) {
int count = 0;
int v = 0;
for (int j = 0; j < arr1[0].length; j++) {
if (arr1[i][j] == 1) {
count++;
if (count == 2) {
count = 1;
sum += v;
v = 0;
}
} else {
if (count > 0) {
v++;
}
}
}
}
System.out.println(sum);
}
}
Arrays.stream(arr).max().orElse(0)
这行代码使用了 Java 8 中的流式操作。每个部分的含义:
-
对于给定的数组 arr,Arrays.stream(arr) 方法将其转换为一个流(Stream)对象。流是用于在一系列元素上执行操作的一种高级抽象。
-
然后,我们使用 .max() 方法来获取流中的最大值。这将返回一个 Optional 类型的对象,它可以包含一个整数值(如果流中有元素),或者为空(如果流为空)。
-
最后,我们使用 .orElse(0) 方法指定一个默认值。如果 Optional 对象为空,则返回指定的默认值,否则返回 Optional 中包含的值。
-
在这个特定的例子中,如果数组 arr 不为空,.max() 方法将返回一个 Optional 对象,其中包含数组中的最大值。如果数组为空,.max() 方法将返回一个空的 Optional 对象。接着,.orElse(0) 方法将被调用,如果 Optional 为空,则返回默认值 0。
整个表达式 Arrays.stream(arr).max().orElse(0) 的作用是:获取数组 arr 中的最大值,如果数组为空,则返回默认值 0。
2. 迷宫游戏【拓展】
在一个二维数组中,0 表示空地,1 表示墙壁,9 表示目标点。你的任务是从起始点 (0, 0)出发,判断是否能够到达目标点,不能斜着移动。
public class Work1002 {
public static void main(String[] args) {
int[][] arr = {
{0, 0, 0, 0, 0},
{1, 1, 0, 1, 0},
{0, 0, 0, 0, 0},
{0, 1, 1, 1, 1},
{0, 0, 0, 0, 9}
};
boolean canReach = canReachTarget(arr);
System.out.println(canReach ? "可以到达目标点" : "无法到达目标点");
}
public static boolean canReachTarget(int[][] maze) {
int m = maze.length; // 行数
int n = maze[0].length; // 列数
boolean[][] visited = new boolean[m][n]; // 标记数组,记录是否访问过
return dfs(maze, 0, 0, visited);
}
private static boolean dfs(int[][] maze, int i, int j, boolean[][] visited) {
if (i < 0 || i >= maze.length || j < 0 || j >= maze[0].length || maze[i][j] == 1 || visited[i][j]) {
return false; // 越界、遇到墙壁或已经访问过的位置,返回false
}
if (maze[i][j] == 9) {
System.out.println("到达目标点 (" + i + ", " + j + ")");
return true; // 找到目标点,返回true
}
visited[i][j] = true; // 标记当前位置为已访问
System.out.println("移动到位置 (" + i + ", " + j + ")");
// 分别尝试上、下、左、右四个方向的移动
boolean canReach = dfs(maze, i - 1, j, visited) ||
dfs(maze, i + 1, j, visited) ||
dfs(maze, i, j - 1, visited) ||
dfs(maze, i, j + 1, visited);
visited[i][j] = false; // 回溯,取消当前位置的标记
return canReach;
}
}
3. 九宫格求和
一个二维数组,找出最小值,求以最小值为中心的九宫格的和,如果九宫格空缺,空缺位置用0补充。
public class Learn1001 {
public static void main(String[] args) {
int[][] arr = {
{9, 10, 11, 12},
{100, 20, 30, 40},
{13, 14, 15, 16},
{5, 6, 7, 10},
};
int n = arr.length;
int m = arr[0].length;
// 求最小值
int[] index = new int[2];
int min = arr[0][0];
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (arr[i][j] < min){
min = arr[i][j];
index[0] = i;
index[1] = j;
}
}
}
System.out.println(Arrays.toString(index));
int sum = 0;
for (int i = index[0] - 1; i <= index[0] + 1; i++) {
for (int j = index[1] - 1; j <= index[1] + 1; j++) {
if (i >=0 && i < n && j >= 0 && j < m) {
sum += arr[i][j];
} else {
sum += 0;
}
}
}
System.out.println(sum);
}
}