有一个 异形 容器,用一个 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。
在一个二维数组中,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;
}
}
一个二维数组,找出最小值,求以最小值为中心的九宫格的和,如果九宫格空缺,空缺位置用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);
}
}