public class Solution {
public boolean canCross(int[] stones) {
Map<Integer, Set<Integer>> map = new HashMap<>();
int n = stones.length;
int target = stones[n - 1];
for (int pos : stones) {
map.put(pos, new HashSet<Integer>());
}
map.get(0).add(1);
for (int pos : stones) {
for (int step : map.get(pos)) {
int nextPos = pos + step;
if (nextPos == target) return true;
if (map.containsKey(nextPos)) {
if (step > 1) map.get(nextPos).add(step - 1);
map.get(nextPos).add(step);
map.get(nextPos).add(step + 1);
}
}
}
return false;
}
}
public class Solution {
public boolean canCross(int[] stones) {
if (stones[0] != 0 || stones[1] != 1) {
return false;
}
// map key is stones' position i, value is every possible steps frog can jump in stones[i]
Map<Integer, Set<Integer>> map = new HashMap<Integer, Set<Integer>>();
for (int i = 0; i < stones.length; i++) {
map.put(stones[i], new HashSet<Integer>());
}
map.get(0).add(1);
// Time = O(stones.length ^ 2)
for (int i = 0; i < stones.length; i++) {
for (int step : map.get(stones[i])) {
if (stones[i] + step == stones[stones.length - 1]) {
return true;
}
Set<Integer> set = map.get(stones[i] + step);
if (set != null) {
set.add(step);
set.add(step + 1);
if (step > 1) {
set.add(step - 1);
}
map.put(stones[i] + step, set);
}
}
}
return false;
}
}
public class Solution {
public boolean canCross(int[] stones) {
if (stones == null || stones.length == 0) {return false;}
int n = stones.length;
if (n == 1) {return true;}
if (stones[1] != 1) {return false;}
if (n == 2) {return true;}
int last = stones[n - 1];
HashSet<Integer> hs = new HashSet();
for (int i = 0; i < n; i++) {
if (i > 3 && stones[i] > stones[i - 1] * 2) {return false;} // The two stones are too far away.
hs.add(stones[i]);
}
return canReach(hs, last, 1, 1);
}
private boolean canReach(HashSet<Integer> hs, int last, int pos, int jump) {
if (pos + jump - 1 == last || pos + jump == last || pos + jump + 1 == last) {
return true;
}
if (hs.contains(pos + jump + 1)) {
if (canReach(hs, last, pos + jump + 1, jump + 1)) {return true;}
}
if (hs.contains(pos + jump)) {
if (canReach(hs, last, pos + jump, jump)) {return true;}
}
if (jump > 1 && hs.contains(pos + jump - 1)) {
if (canReach(hs, last, pos + jump - 1, jump - 1)) {return true;}
}
return false;
}
}