二維數組是演算法入門的核心數據結構。本文通過一個綜合案例,實現**隨機二維數組生成、行最大值統計、列平均值計算、鞍點查找、楊輝三角打印**五大經典操作,代碼結構清晰,邏輯講解詳細,適合夯實數組操作基本功。
public class Array2DDemo {
public static void main(String[] args) {
int[][] matrix = generateRandomMatrix(10, 10, 10); // 10x10, 0-9
printMatrix(matrix, "原始矩陣");
int[] rowMax = getRowMax(matrix);
printArray(rowMax, "各行最大值");
double[] colAvg = getColAvg(matrix);
printArray(colAvg, "各列平均值");
int[] saddlePoints = findSaddlePoints(matrix);
if (saddlePoints.length == 0) {
System.out.println("鞍點:無");
} else {
printArray(saddlePoints, "鞍點值");
}
printYangHuiTriangle(10);
}
// 1. 生成隨機矩陣
public static int[][] generateRandomMatrix(int rows, int cols, int bound) {
int[][] m = new int[rows][cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
m[i][j] = (int) (Math.random() * bound);
}
}
return m;
}
// 2. 打印矩陣
public static void printMatrix(int[][] m, String title) {
System.out.println("=== " + title + " ===");
for (int[] row : m) {
for (int val : row) System.out.printf("%4d", val);
System.out.println();
}
}
// 3. 打印一維數組
public static void printArray(int[] arr, String title) {
System.out.print(title + ": ");
for (int v : arr) System.out.print(v + " ");
System.out.println();
}
public static void printArray(double[] arr, String title) {
System.out.print(title + ": ");
for (double v : arr) System.out.printf("%.2f ", v);
System.out.println();
}
// 4. 各行最大值
public static int[] getRowMax(int[][] m) {
int[] max = new int[m.length];
for (int i = 0; i < m.length; i++) {
int rowMax = m[i][0];
for (int j = 1; j < m[i].length; j++) {
if (m[i][j] > rowMax) rowMax = m[i][j];
}
max[i] = rowMax;
}
return max;
}
// 5. 各列平均值
public static double[] getColAvg(int[][] m) {
int rows = m.length, cols = m[0].length;
double[] avg = new double[cols];
for (int j = 0; j < cols; j++) {
long sum = 0;
for (int i = 0; i < rows; i++) sum += m[i][j];
avg[j] = (double) sum / rows;
}
return avg;
}
// 6. 查找鞍點:行最大且列最小
public static int[] findSaddlePoints(int[][] m) {
List<Integer> points = new ArrayList<>();
int rows = m.length, cols = m[0].length;
for (int i = 0; i < rows; i++) {
// 先找該行最大值及其列索引 (可能有多個相同最大值)
int rowMax = m[i][0];
for (int j = 1; j < cols; j++) if (m[i][j] > rowMax) rowMax = m[i][j];
// 檢查該行所有等於 rowMax 的元素是否為列最小
for (int j = 0; j < cols; j++) {
if (m[i][j] == rowMax) {
boolean isColMin = true;
for (int k = 0; k < rows; k++) {
if (m[k][j] < rowMax) { isColMin = false; break; }
}
if (isColMin) points.add(rowMax);
}
}
}
return points.stream().mapToInt(Integer::intValue).toArray();
}
// 7. 楊輝三角
public static void printYangHuiTriangle(int n) {
System.out.println("=== 楊輝三角前 " + n + " 行 ===");
int[][] triangle = new int[n][];
for (int i = 0; i < n; i++) {
triangle[i] = new int[i + 1];
for (int j = 0; j <= i; j++) {
if (j == 0 || j == i) triangle[i][j] = 1; // 兩邊為 1
else triangle[i][j] = triangle[i-1][j-1] + triangle[i-1][j]; // 內部 = 左上 + 右上
}
}
// 美化打印:居中對齊
int maxWidth = String.valueOf(triangle[n-1][n/2]).length() + 1; // 最大數字寬度
for (int i = 0; i < n; i++) {
// 前導空格
for (int s = 0; s < (n - i - 1) * maxWidth / 2; s++) System.out.print(" ");
for (int j = 0; j <= i; j++) {
System.out.printf("%" + maxWidth + "d", triangle[i][j]);
}
System.out.println();
}
}
}
| 功能 | 關鍵算法 | 時間複雜度 | 注意點 |
|---|---|---|---|
| 行最大值 | 單層循環掃描每行 | O(rows × cols) | 初始化 rowMax = row[0],避免負數干擾 |
| 列平均值 | 列優先循環累加求和 | O(rows × cols) | 用 long 累加防溢出,除以 rows 轉 double |
| 鞍點查找 | 行掃描找最大 → 列掃描驗證最小 | O(rows × cols × min(rows,cols)) | 一行可能有多個最大值,需逐個驗證;若無鞍點返回空數組 |
| 楊輝三角 | 動態規劃:`dp[i][j] = dp[i-1][j-1] + dp[i-1][j]` | O(n²) | 邊界 j==0 或 j==i 為 1;打印時計算最大數字寬度對齊 |
二維數組操作核心在於**雙重循環遍歷順序控制** (行優先/列優先) 和**邊界條件處理**。掌握本案例五大操作,即掌握了矩陣統計、特徵值查找、動態規劃填表三大核心模式。建議進一步練習:矩陣轉置、旋轉 90°、螺旋遍歷、最短路徑 (DP)、稀疏矩陣壓縮存儲。