|
@@ -1,34 +1,41 @@
|
|
|
func canCross(stones []int) bool {
|
|
|
n := len(stones)
|
|
|
- m := make(map[int]int)
|
|
|
+ if n == 1 {
|
|
|
+ return true
|
|
|
+ } else if n == 0 || stones[1] != 1 {
|
|
|
+ return false
|
|
|
+ }
|
|
|
+ m := make(map[int]bool)
|
|
|
for i := 1; i < n; i++ {
|
|
|
- m[stones[i]] = i
|
|
|
+ if 2*stones[i-1]+1 < stones[i] {
|
|
|
+ return false // Pruning when the gap is too large.
|
|
|
+ }
|
|
|
+ m[stones[i]] = true
|
|
|
}
|
|
|
- steps := make([][]int, n)
|
|
|
- steps[0] = []int{0}
|
|
|
- return dfs(stones, m, n, 0, &steps)
|
|
|
+ return dfs(m, stones[n-1], 1, 1)
|
|
|
}
|
|
|
|
|
|
-func dfs(stones []int, m map[int]int, n, i int, steps *[][]int) bool {
|
|
|
- if i == n-1 {
|
|
|
+func dfs(m map[int]bool, end, pos, jump int) bool {
|
|
|
+ if pos+jump+1 == end || pos+jump == end || pos+jump-1 == end {
|
|
|
return true
|
|
|
}
|
|
|
- for _, l := range (*steps)[i] {
|
|
|
- for j := maxInt(1, l-1); j <= l+1; j++ {
|
|
|
- if idx, ok := m[stones[i]+j]; ok {
|
|
|
- (*steps)[idx] = append((*steps)[idx], j)
|
|
|
- if dfs(stones, m, n, idx, steps) {
|
|
|
- return true
|
|
|
- }
|
|
|
- }
|
|
|
+ if _, ok := m[pos+jump+1]; ok {
|
|
|
+ if dfs(m, end, pos+jump+1, jump+1) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if _, ok := m[pos+jump]; ok {
|
|
|
+ if dfs(m, end, pos+jump, jump) {
|
|
|
+ return true
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if jump == 1 { // 0 is not valid
|
|
|
+ return false
|
|
|
+ } else if _, ok := m[pos+jump-1]; ok {
|
|
|
+ if dfs(m, end, pos+jump-1, jump-1) {
|
|
|
+ return true
|
|
|
}
|
|
|
}
|
|
|
return false
|
|
|
}
|
|
|
|
|
|
-func maxInt(x, y int) int {
|
|
|
- if x < y {
|
|
|
- return y
|
|
|
- }
|
|
|
- return x
|
|
|
-}
|