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步是否能够到达下一节点,再按步骤继续下去。
解法二:
用到动态规划的解法,用空间效率换取时间效率。用一个Hashmap存放每个节点能够跳跃的步数集合,从第一个节点开始,遍历前一个节点能够走的步数集合,计算跳跃指定可跳步数后的下个节点,判断该节点是否为最后一个节点,如果不是再计算该节点能够跳跃的步数,再进行遍历。最后,如果整个循环没有任何return遍历结束,则证明该数组不能跳跃到最后节点。
给定一串数组,从第一个数字节点开始,向后跳跃,跳跃规则是,只能从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; } }
相关文章推荐
- leetcode 741. Cherry Pickup 来回摘樱桃 + 深度优先遍历DFS + 动态规划DP
- Leetcode No.104 Maximum Depth of Binary Tree 遍历二叉树的深度
- leetcode 392. Is Subsequence 子序列判断 深度优先遍历DFS + 一个很简单的循环
- leetcode 529. Minesweeper 扫雷游戏 + 经典的DFS深度优先遍历
- leetcode 101. Symmetric Tree BFS广度优先遍历+DFS深度优先遍历
- leetcode 687. Longest Univalue Path 二叉树最长相等路径+ 深度优先遍历DFS
- leetcode 235. Lowest Common Ancestor of a Binary Search Tree 二叉搜索树BST的最近公共祖先LCA + 深度优先遍历DFS
- leetcode 282. Expression Add Operators 任意添加运算符计算结果 +深度优先遍历DFS
- Leetcode-403.Frog Jump(青蛙跳石头)
- leetcode 623. Add One Row to Tree二叉树添加指定深度元素+ 深度优先遍历DFS
- leetcode 753. Cracking the Safe 深度优先遍历DFS
- leetcode 222. Count Complete Tree Nodes 计算满二叉树的节点数量 + DFS深度优先遍历 + 公式计算
- leetcode 337. House Robber III DP动态规划 + DFS深度有限遍历
- leetcode 51. N-Queens DFS深度优先遍历
- leetcode 526. Beautiful Arrangement 递归实现全排列 + 经典深度优先遍历DFS做法
- 【LeetCode】Path Sum 2 --java 二叉数 深度遍历,保存路径
- leetcode 100. Same Tree 二叉树DFS深度优先遍历
- leetcode 101. Symmetric Tree-对称二叉数|深度遍历
- leetcode 139. Word Break 深度优先遍历DFS按照index递归搜索 + 很棒的动态规划DP做法
- leetcode 236. Lowest Common Ancestor of a Binary Tree 最近公告祖先LCA + 二叉树 + 深度优先遍历DFS