如何在n×n矩阵中实现对角线之字形路径遍历并规避索引越界错误
实现矩阵之字形对角线路径生成与索引越界规避
咱们先来明确核心需求:从n×n矩阵的每个单元格出发,每一步只能向下移动一行,同时选择**右对角线(行+1,列+1)或左对角线(行+1,列-1)**方向,生成所有从起点到最后一行的完整路径,最终输出成连续数字字符串。同时要彻底避免索引越界问题。
原代码的问题点
你的现有代码框架只是完成了矩阵的构建,但缺少回溯/递归探索路径的核心逻辑,也没有处理移动方向的边界检查,所以无法生成所有可能的路径。
解决方案:回溯法+严格边界检查
我们用递归回溯来遍历所有可能的路径,每一步移动前先检查索引合法性,从根源上避免IndexOutOfBoundsException。
核心逻辑拆解
- 矩阵构建:正确解析输入字符串,填充n×n矩阵(注意原代码中
size变量未定义,要替换为你指定的s)。 - 回溯探索:从每个单元格出发,递归向下探索两种对角线方向:
- 每次移动前,检查新的列索引是否在
0 ≤ col < n范围内(行索引是当前行+1,最多到n-1,不会越界)。 - 当走到最后一行时,输出当前路径的连续数字。
- 每次移动前,检查新的列索引是否在
- 路径传递:用字符串或
StringBuilder记录路径,注意递归时的路径隔离(避免不同路径互相干扰)。
完整修改后的代码
import java.util.Scanner; public class ZigZagMatrixPaths { public static void main(String[] args) { int s = 4; // 矩阵大小,可根据输入动态调整 int k = 0; String[][] grid = new String[s][s]; Scanner sc = new Scanner(System.in); // 解析输入字符串,构建矩阵 String[] in = sc.nextLine().trim().split("\\s+"); for (int i = 0; i < s; i++) { for (int j = 0; j < s; j++) { grid[i][j] = in[k]; k++; } } sc.close(); // 遍历所有单元格作为起点 for (int i = 0; i < s; i++) { for (int j = 0; j < s; j++) { // 启动回溯,初始路径是起点值 findPaths(grid, s, i, j, grid[i][j]); } } } /** * 递归回溯查找所有路径 * @param grid 矩阵 * @param size 矩阵大小 * @param currRow 当前所在行 * @param currCol 当前所在列 * @param currentPath 当前已生成的路径 */ private static void findPaths(String[][] grid, int size, int currRow, int currCol, String currentPath) { // 到达最后一行,输出完整路径 if (currRow == size - 1) { System.out.println(currentPath); return; } // 尝试右对角线方向:行+1,列+1 int nextRow = currRow + 1; int nextColRight = currCol + 1; if (nextColRight < size) { // 检查列是否越界(行nextRow最多是size-1,不会越界) findPaths(grid, size, nextRow, nextColRight, currentPath + grid[nextRow][nextColRight]); } // 尝试左对角线方向:行+1,列-1 int nextColLeft = currCol - 1; if (nextColLeft >= 0) { // 检查列是否越界 findPaths(grid, size, nextRow, nextColLeft, currentPath + grid[nextRow][nextColLeft]); } } }
关键细节说明
- 索引越界规避:每次尝试移动方向前,都会检查
nextColRight < size和nextColLeft >= 0,确保列索引始终在合法范围内。行索引因为是currRow+1,而只有当currRow < size-1时才会进入递归(否则直接输出),所以nextRow最多是size-1,不会越界。 - 路径生成:递归时直接拼接字符串传递路径(如果矩阵很大,建议用
StringBuilder并在回溯后撤销操作,优化内存)。 - 起点覆盖:遍历所有
(i,j)作为起点,确保不会遗漏任何可能的路径。
测试示例
输入你提供的字符串:
6 4 7 5 3 8 9 2 1 5 1 7 1 6 2 8
程序会输出所有符合要求的路径,比如:
6816 6818 4351 4352 4952 4951 4972 ...
内容的提问来源于stack exchange,提问作者Jordan
相关产品推荐
相关产品推荐

