递归数组路径判定问题求助:可达终点却返回false
解决你的递归路径判断问题
我来帮你排查这个问题哈!你的代码现在明明应该返回true的测试用例却输出false,核心问题是递归时只尝试了单一路径,没有回溯去尝试另一条可能的路径,还有几处逻辑判断的小问题,咱们一步步来修复:
你的代码存在的问题
- 单一路径尝试,未回溯:当当前索引既可以向右又可以向左移动时,你现在只走了其中一条路就直接返回结果,如果这条路走不通,就直接返回false了,完全没机会尝试另一条路径。
- 无法移动的判断逻辑错误:你写的
!((a[i]+i < a.length) && (i-a[i] >= 0))意思是“不是(既能向右又能向左)”,也就是只要其中一个方向走不了就返回false,但实际上只要有一个方向能走就应该继续尝试,正确的逻辑应该是两个方向都走不了才返回false。 - 修改原数组导致的副作用:你把
a[i]设为-1标记已访问,但递归返回时没有恢复这个值,导致后续尝试其他路径时,原数组的标记会影响判断,而且还破坏了输入数组的原始数据。
修复后的代码
我重新调整了递归逻辑,用单独的访问标记数组代替修改原数组,同时处理了回溯和多路径尝试:
public class Ex14 { public static boolean isWay(int[] a) { if(a.length <= 1) return false; // 长度小于等于1,没有可到达的终点 boolean[] visited = new boolean[a.length]; // 用单独数组标记已访问索引,不破坏原数组 return isWay(a, 0, visited); } private static boolean isWay(int[] a, int i, boolean[] visited) { // 到达最后一个单元格,直接返回true if(i == a.length - 1) return true; // 索引越界或已访问过,避免循环或无效路径 if(i < 0 || i >= a.length || visited[i]) return false; // 标记当前索引为已访问,防止重复进入 visited[i] = true; // 计算向右和向左的目标位置 int right = i + a[i]; int left = i - a[i]; // 尝试两条路径:只要其中一条能到达终点,就返回true boolean canReachViaRight = isWay(a, right, visited); boolean canReachViaLeft = isWay(a, left, visited); // 回溯:取消当前索引的访问标记,让其他分支的递归可以再次访问 visited[i] = false; // 只要一条路径可行就返回true return canReachViaRight || canReachViaLeft; } }
关键修改说明
- 新增访问标记数组:用
boolean[] visited代替修改原数组,既避免破坏输入数据,又能有效防止递归时循环访问同一个索引。 - 多路径尝试:用
||逻辑同时尝试向右和向左的路径,只要其中一条路径能到达终点,整体就返回true;如果第一条路径走不通,会自动尝试第二条。 - 回溯处理:在递归返回后取消当前索引的访问标记,这样其他分支的递归可以重新访问这个索引(比如不同路径过来的情况)。
- 更清晰的边界判断:直接通过
i < 0 || i >= a.length判断索引是否越界,替代原来复杂的条件,逻辑更直观。
测试验证
用你的测试用例跑一下:
- 对于
a1 = {2,4,1,6,4,2,4,3,5},路径0→2→3→8(最后一个索引)会被检测到,返回true。 - 对于
a2 = {1,4,3,1,2,4,3},所有可能的路径都无法到达最后一个索引(索引6),返回false,完全符合预期。
内容的提问来源于stack exchange,提问作者asaf
相关产品推荐
相关产品推荐

