这里有一个非负整数数组 arr
,你最开始位于该数组的起始下标 start
处。当你位于下标 i
处时,你可以跳到 i + arr[i]
或者 i - arr[i]
。
请你判断自己是否能够跳到对应元素值为 0 的 任一 下标处。
注意,不管是什么情况下,你都无法跳到数组之外。
示例 1:
输入:arr = [4,2,3,0,3,1,2], start = 5 输出:true 解释: 到达值为 0 的下标 3 有以下可能方案: 下标 5 -> 下标 4 -> 下标 1 -> 下标 3 下标 5 -> 下标 6 -> 下标 4 -> 下标 1 -> 下标 3
示例 2:
输入:arr = [4,2,3,0,3,1,2], start = 0 输出:true 解释: 到达值为 0 的下标 3 有以下可能方案: 下标 0 -> 下标 4 -> 下标 1 -> 下标 3
示例 3:
输入:arr = [3,0,2,1,2], start = 2 输出:false 解释:无法到达值为 0 的下标 1 处。
提示:
1 <= arr.length <= 5 * 10^4
0 <= arr[i] < arr.length
0 <= start < arr.length
这道题算是我第一次独自用递归写出深度优先搜索并解决的第一道题,感觉这段时间刷题有了回报,挺好玩的。
这道题既可以用广度优先搜索,也可以用深度优先搜索。这里用的是深度优先搜索,广度优先以后有机会了补上。
深度优先搜索利用递归可以比较简洁地实现。
如果某个点无法到达题目要求的数值为0的点,则说明这条点的路径都无法到达。可以利用这一点来跳出递归。
需要注意的是形成一个闭环的情况,会导致一直循环而最后栈溢出。
可以利用一个辅助空间来存储是否已经经过了。
刚开始我利用了一个set型变量,每经过一个点,就把这个点存储在set中,如果下次再经过这个点,则返回FALSE。
之后用了一个boolean数组进行了优化。
两次代码如下:
class Solution { private int len; private Set<Integer> set = new HashSet<>(); public boolean canReach(int[] arr, int start) { this.len = arr.length; if (set.contains(start)) { return false; } else { set.add(start); } if (arr[start] == 0) { return true; } int tem1 = start - arr[start]; boolean j1 = false; if (tem1 >= 0) { j1 = canReach (arr, tem1); } int tem2 = arr[start] + start; boolean j2 = false; if (tem2 < len) { j2 = canReach (arr, tem2); } return j1 || j2; } }
运行结果:
优化后代码:
class Solution { public boolean canReach(int[] arr, int start) { int len = arr.length; boolean[] judge = new boolean[len]; return tool(arr, start, judge, len); } private boolean tool (int[] arr, int start, boolean[] judge, int len) { if (judge[start]) { return false; } else { judge[start] = true; } if (arr[start] == 0) { return true; } int tem1 = start - arr[start]; boolean j1 = false; if (tem1 >= 0) { j1 = tool (arr, tem1, judge, len); } int tem2 = arr[start] + start; boolean j2 = false; if (tem2 < len) { j2 = tool (arr, tem2, judge, len); } return j1 || j2; } }
标签:力扣,1306,下标,int,arr,len,---,start,boolean From: https://www.cnblogs.com/allWu/p/17066615.html