您的位置:首页 > 其它

Frog Jump--深度遍历,动态规划--leetcode

2017-08-12 16:18 423 查看
题意:

给定一串数组,从第一个数字节点开始,向后跳跃,跳跃规则是,只能从0开始跳,最先只能跳到1,设上次跳跃步数为k,接下来可跳的步数是k,k-1,k+1,求是否能够到达最后一个数字(规定只能向后跳跃)。

eg.

[0, 1, 3, 5, 6, 8, 12, 17]

0跳k+1=1步到1,上次跳跃步数k=0

1跳k+1=2步到3,上次跳跃步数k=1

3跳k=2步到5,上次跳跃步数k=2

5跳k+1=3步到8,上次跳跃步数k=2

8跳k+1=4步到12,上次跳跃步数k=3

1跳k+1=5步到17,上次跳跃步数k=4

解法一:

用到深度遍历搜索的算法,一直递归向下搜索能够到达的点。从 第一点开始,判断向后走k-1,k,k+1步是否到达终点。没有到达的话再判断向后走k-1步是否能够到达下一节点,如果是则再继续判断判断向后走k-1,k,k+1步是否到达终点,再按步骤继续下去;没有的话再判断向后走k步是否能够到达下一节点,再按步骤继续下去。

public class FrogJumpSolution {

public static void main(String[] args) {
int[] stones = { 0, 1, 3, 5, 6, 8, 12, 17 };
System.out.println(canCross(stones));
}

public static boolean canCross(int[] stones) {
int i = 0, len = stones.length;
HashSet<Integer> set = new HashSet<Integer>();
if (len == 1) {
if (stones[0] != 0) {
return false;
}
} else if (len == 2) {
if (stones[0] != 0 || stones[1] != 1) {
return false;
}
} else {
for (i = 0; i < len - 1; i++) {
if (i > 2 && stones[i] * 2 <= stones[i + 1]) {
return false;
}
set.add(stones[i]);
}
return canReach(set, 1, 1, stones[len - 1]);
}
return true;
}

public static boolean canReach(HashSet<Integer> set, int curPos, int lastJump, int lastPos) {
if (lastPos == curPos + lastJump + 1 || lastPos == curPos + lastJump || lastPos == curPos + lastJump - 1) {
return true;
}
//先跳跃较大的步数,减少递归次数
if (set.contains(curPos + lastJump + 1)) {
if (canReach(set, curPos + lastJump + 1, lastJump + 1, lastPos)) {
return true;
}
}
if (set.contains(curPos + lastJump)) {
if (canReach(set, curPos + lastJump, lastJump, lastPos)) {
return true;
}
}
//由于只能向前走,此处满足k-1向前走的条件是k>1
if (lastJump > 1 && set.contains(curPos + lastJump - 1)) {
if (canReach(set, curPos + lastJump - 1, lastJump - 1, lastPos)) {
return true;
}
}
return false;
}
}


解法二:

用到动态规划的解法,用空间效率换取时间效率。用一个Hashmap存放每个节点能够跳跃的步数集合,从第一个节点开始,遍历前一个节点能够走的步数集合,计算跳跃指定可跳步数后的下个节点,判断该节点是否为最后一个节点,如果不是再计算该节点能够跳跃的步数,再进行遍历。最后,如果整个循环没有任何return遍历结束,则证明该数组不能跳跃到最后节点。

public class Solution {
public boolean canCross(int[] stones) {
if (stones.length == 0) {
return true;
}

HashMap<Integer, HashSet<Integer>> map = new HashMap<Integer, HashSet<Integer>>(stones.length);
map.put(0, new HashSet<Integer>());
map.get(0).add(1);
for (int i = 1; i < stones.length; i++) {
map.put(stones[i], new HashSet<Integer>() );
}

for (int i = 0; i < stones.length - 1; i++) {
int stone = stones[i];
for (int step : map.get(stone)) {
int reach = step + stone;
if (reach == stones[stones.length - 1]) {
return true;
}
HashSet<Integer> set = map.get(reach);
if (set != null) {
set.add(step);
if (step - 1 > 0) set.add(step - 1);
set.add(step + 1);
}
}
}

return false;
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐