Mr.Mou @ ShiShi AP Center

CSA 2DArray 必考算法

2D 数组核心算法详解 (AP CSA 范围)

Setup: 基础 2D 数组准备

public class TwoDArrayAlgorithms {
    public static void main(String[] args) {
        // 初始化一个 3行 4列 的二维数组
        int[][] grid = {
            {3,  5,  1,  7},
            {9,  2,  6,  4},
            {8, 10, 12, 11}
        };

        // AP CSA 标准打印方法:嵌套 for 循环
        for (int r = 0; r < grid.length; r++) { // 遍历每一行
            for (int c = 0; c < grid[r].length; c++) { // 遍历当前行的每一列
                System.out.print(grid[r][c] + " ");
            }
            System.out.println(); // 换行
        }
    }
}

1. 确定最大值或最小值 (Min/Max)

查找整个 2D 数组的最大值

public class MaxIn2D {
    public static void main(String[] args) {
        int[][] grid = {
        {3, 5, 1}, 
        {9, 2, 6}, 
        {8, 10, 12}
        };

        int max = grid[0][0]; // 初始化最大值为第一个元素
        
        // 方法 A: 使用索引嵌套循环
        for (int r = 0; r < grid.length; r++) {
            for (int c = 0; c < grid[r].length; c++) {
                if (grid[r][c] > max) {
                    max = grid[r][c];
                }
            }
        }

        // 方法 B: 使用增强型 for 循环 (更简洁)
        max = grid[0][0];
        for (int[] row : grid) {      // 每一行是一个 int[]
            for (int val : row) {     // 遍历行中的每个元素
                if (val > max) {
                    max = val;
                }
            }
        }
        System.out.println("最大值: " + max);
    }
}

查找指定列 (Column) 的最大值

public class MaxInColumn {
    public static void main(String[] args) {
        int[][] grid = {
        {3, 5, 1}, 
        {9, 2, 6}, 
        {8, 10, 12}
        };
        int targetCol = 1; // 目标列索引

        // 查找某一列时,列索引固定,行索引变化
        int max = grid[0][targetCol];
        for (int r = 1; r < grid.length; r++) {
            if (grid[r][targetCol] > max) {
                max = grid[r][targetCol];
            }
        }
        System.out.println("第 " + targetCol + " 列的最大值: " + max);
    }
}

2. 计算总和与平均数 (Sum/Average)

计算子区域 (Subsection) 的平均数

public class AverageSubsection {
    public static void main(String[] args) {
        int[][] grid = {
        {3, 5, 1, 7}, 
        {9, 2, 6, 4}, 
        {8, 10, 12, 11}
        };

        int r0 = 0, r1 = 1; // 行范围 [0, 1]
        int c0 = 1, c1 = 3; // 列范围 [1, 3]
        int sum = 0;
        int count = 0;

        for (int r = r0; r <= r1; r++) {
            for (int c = c0; c <= c1; c++) {
                sum += grid[r][c];
                count++;
            }
        }

        // 强转 double 确保计算精度
        double avg = (double) sum / count;
        System.out.println("子区域平均值: " + avg);
    }
}

3. 判断是否至少有一个元素符合条件 (At Least One)

检查是否存在偶数

public class AnyEven2D {
    public static void main(String[] args) {
        int[][] grid = {
        {3, 5, 1}, 
        {9, 2, 6}
        };
        boolean found = false;

        // 使用 !found 标志位控制循环,避免使用 break
        for (int r = 0; r < grid.length && !found; r++) {
            for (int c = 0; c < grid[r].length && !found; c++) {
                if (grid[r][c] % 2 == 0) {
                    found = true;
                }
            }
        }
        System.out.println("是否存在偶数: " + found);
    }
}

4. 统计符合条件的元素数量 (Count)

统计某一列中偶数的个数

public class CountEvenCol {
    public static void main(String[] args) {
        int[][] grid = {
        {2, 5}, 
        {4, 2}, 
        {7, 10}
        };
        int targetCol = 0;
        int count = 0;

        for (int r = 0; r < grid.length; r++) {
            if (grid[r][targetCol] % 2 == 0) {
                count++;
            }
        }
        System.out.println("该列偶数数量: " + count);
    }
}

5. 访问所有相邻元素对 (Pairs)

垂直邻居 (同一列,相邻行)

public class ConsecutiveVertical {
    public static void main(String[] args) {
        int[][] grid = {
        {3, 5}, 
        {9, 2}, 
        {8, 10}
        };

        int cols = grid[0].length;
        for (int c = 0; c < cols; c++) {
            // 注意:r 只能到 length - 1,防止 r + 1 越界
            for (int r = 0; r < grid.length - 1; r++) {
                System.out.println("垂直相邻对: " + grid[r][c] + " 和 " + grid[r + 1][c]);
            }
        }
    }
}

6. 检查是否存在重复元素 (Duplicates)

检查整个 2D 数组是否有重复值

public class DuplicateCheck2D {
    public static void main(String[] args) {
        int[][] grid = {
        {1, 2}, 
        {3, 1}
        };
        boolean hasDup = false;

        // 将每个位置 (r1, c1) 与其他所有位置 (r2, c2) 进行比较
        for (int r1 = 0; r1 < grid.length && !hasDup; r1++) {
            for (int c1 = 0; c1 < grid[r1].length && !hasDup; c1++) {
                
                for (int r2 = 0; r2 < grid.length && !hasDup; r2++) {
                    for (int c2 = 0; c2 < grid[r2].length && !hasDup; c2++) {
                        // 排除自己跟自己比较的情况
                        if (r1 != r2 || c1 != c2) {
                            if (grid[r1][c1] == grid[r2][c2]) {
                                hasDup = true;
                            }
                        }
                    }
                }
            }
        }
        System.out.println("是否存在重复: " + hasDup);
    }
}

7. 移动或旋转元素 (Shift/Rotate)

将某一列向下移动一位 (首尾衔接)

public class ShiftColumnDown {
    public static void main(String[] args) {
        int[][] grid = {
        {1, 2}, 
        {3, 4}, 
        {5, 6}
        };
        int col = 0;

        // 1. 暂存最底部的元素
        int temp = grid[grid.length - 1][col];

        // 2. 从下往上覆盖,确保数据不会被提前覆盖
        for (int r = grid.length - 1; r > 0; r--) {
            grid[r][col] = grid[r - 1][col];
        }

        // 3. 将暂存的元素放到最顶部
        grid[0][col] = temp;
    }
}

8. 反转元素 (Reverse)

原地反转某一列

public class ReverseColumn {
    public static void main(String[] args) {
        int[][] grid = {
        {1, 0}, 
        {2, 0}, 
        {3, 0}, 
        {4, 0}
        };
        int col = 0;

        // 交换该列的上半部分和下半部分
        for (int r = 0; r < grid.length / 2; r++) {
            int temp = grid[r][col];
            int oppositeRow = grid.length - 1 - r;
            grid[r][col] = grid[oppositeRow][col];
            grid[oppositeRow][col] = temp;
        }
    }
}