这个是 LintCode 上面的一道算法问题--青蛙跳

问题描述:

        一只青蛙正要过河,这条河分成了 x 个单位,每个单位可能存在石头,青蛙可以跳到石头上,但它不能跳进水里。按照顺序给出石头所在的位置,判断青蛙能否到达最后一块石头所在的位置。刚开始时青蛙在第一块石头上,假设青蛙第一次跳只能跳一个单位的长度。如果青蛙最后一个跳 k 个单位,那么它下一次只能跳 k - 1 ,k 或者 k + 1 个单位。注意青蛙只能向前跳。

注意事项:

        石头的个数 >= 2并且 <= 1100。每块石头的位置是一个非负数并且 < 2^31。第一块石头的位置总是 0.

样例说明:

        给出石头的位置为 [0,1,3,5,6,8,12,17]总共8块石头。第一块石头在 0 位置,第二块石头在 1 位置,第三块石头在 3 位置等等......最后一块石头在 17 位置。返回 true。青蛙可以通过跳 1 格到第二块石头,跳 2 格到第三块石头,跳 2 格到第四块石头,跳 3 格到第六块石头,跳 4 格到第七块石头,最后跳 5 格到第八块石头。给出石头的位置为 `[0,1,2,3,4,8,9,11]`返回 false。青蛙没有办法跳到最后一块石头因为第五块石头跟第六块石头的距离太大了。

问题分析:

1.青蛙每跳到一块石头上面,下一步就有三种选择,

k - 1 ,k 或者 k + 1 个单位

2.当青蛙跳到下一个石头上面的时候,就更加靠近了对岸,然后我们又可以在以下一个石头为起点,以同样的思路分析问题,但是问题的规模更小了,当跳到最后一块石头上面的时候,就结束了。这个思路符合递归算法的本质。

解决代码:

/*** 2018-04-30* @author liujie**/
public class TestCanCross {public boolean canCross(int[] stones){if (stones == null || stones.length < 2) return true;//这一步只是为了过滤掉一些明显错误的数据,比如说//{0,1,2,3,4,5,6,7,8,9,10,.....995,996,997,998,99999999}//这种数据,某一块和之前一块石头的距离明显过大,就不用放到程序里面验证了,不然太耗时间for (int i = stones.length - 1; i > 2; i --) {if (stones[i] > 2 * stones[i - 1]) return false;}//假设青蛙总能跳出第一步return canCross(stones, 1, stones[1]);}private boolean canCross(int[] stones, int currentLocation, int lastStep) {//这是base case, 当青蛙跳到了最后一块石头上面,说明成功了if (currentLocation == stones.length - 1) return true;int next = 0;//能找到下一个步距为lastStep + 1的石头,并且调到测试下一个石头是否能成功if ((next = findNextLocation(stones, currentLocation, lastStep + 1)) != -1&& canCross(stones, next, lastStep + 1))return true;if ((next = findNextLocation(stones, currentLocation, lastStep)) != -1&& canCross(stones, next, lastStep))return true;if ((next = findNextLocation(stones, currentLocation, lastStep - 1)) != -1&& canCross(stones, next, lastStep - 1))return true;return false;}/*** 找到当前石头后,一个相距为dumpStep的石头* @param stones* @param currentLocation    当前石头位置* @param dumpStep            测试的距离* @return 如果正好找到一个石头,与当前石头的位置相距为dumpStep,则返回该石头的下标*/private int findNextLocation(int[] stones, int currentLocation, int dumpStep) {//从当前下标开始,一个一个往后移动,寻找相距为dumpStep的下标for (int i = currentLocation + 1; i < stones.length; i ++){if (stones[i] - stones[currentLocation] == dumpStep) return i;//因为是递增的数组,如果这个距离都已经大于dumpStep了,后面就更不可能了if (stones[i] - stones[currentLocation] > dumpStep) return -1;}//找遍数组也没有找到,返回一个默认值return -1;}}

代码细节:

                if ((next = findNextLocation(stones, currentLocation, lastStep + 1)) != -1   && canCross(stones, next, lastStep + 1))return true;if ((next = findNextLocation(stones, currentLocation, lastStep)) != -1&& canCross(stones, next, lastStep))return true;if ((next = findNextLocation(stones, currentLocation, lastStep - 1)) != -1&& canCross(stones, next, lastStep - 1))return true;return false;

这一部分是整个代码的核心递归

1.采用的是lastStep + 1, lastStep, lastStep - 1的顺序,主要是为了在三者都符合时,尽量跳大一点的距离

2.采用的是

                if ((next = findNextLocation(stones, currentLocation, lastStep + 1)) != -1   && canCross(stones, next, lastStep + 1))return true;

而不是

        if ((next = findNextLocation(stones, currentLocation, lastStep + 1)) != -1 )return canCross(stones, next, lastStep + 1);

因为可能找到lastStep + 1的步距石头,但是下一个石头不一定就能成功,但也不一定失败,可能 lastStep或者lastStep - 1就能成功,他们三者就是平等的,

青蛙跳 LintCode青蛙过河问题相关推荐

  1. Java小青蛙跳台街,青蛙跳台阶问题:Java版,递归算法和循环

    青蛙跳台阶 青蛙跳台阶,青蛙每一次可以跳1阶或2阶,假设有n阶台阶,青蛙要跳完所有台阶,有多少种跳法? 引入斐波那契数列 对于斐波那契数列,百度百科是这么解释的: 斐波那契数列(Fibonacci s ...

  2. 青铜三人行之青蛙跳台阶

    先说一个消息,为了方便互相交流学习,青铜三人行建了个微信群,感兴趣的伙伴可以扫码加下面的小助手抱你入群哦! 青蛙跳台阶问题 青铜三人行--每周一题@青蛙跳台阶 青蛙跳台阶问题 一只青蛙一次可以跳上1级 ...

  3. 买卖股票最佳时机+青蛙跳楼梯

    1.买卖股票最佳时机 数组 numbers: [1,2,6,3,4] 想求的最佳买卖时机,暴力解法,可以使用for循环,循环两次,查看最大差值 较优方案:动态规划 初始化一个Min值和一个Max值,m ...

  4. 自制青蛙跳台阶小游戏~

    青蛙跳台阶小游戏 1.概念(concept)文档 楔子(Setting):千百年来,人们在贬低别人时,常用井底之蛙来描述那个人,但这却让青蛙不开心了,于是青蛙决定跳出井底,为自己讨一个公道. 玩法(G ...

  5. [递归]一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果)。

    这题是用C写的~ 在牛客上半天找不着ACM模式,练习模式里只有核心代码模式 这样用C语言编译器就不能自定义函数啊,不鸡肋吗??? 解决方法:在核心代码模式下用C++编译器(反正C++完全兼容C的不是吗 ...

  6. 剑指offer:面试题10- II. 青蛙跳台阶问题

    题目:青蛙跳台阶问题 一只青蛙一次可以跳上1级台阶,也可以跳上2级台阶.求该青蛙跳上一个 n 级的台阶总共有多少种跳法. 答案需要取模 1e9+7(1000000007),如计算初始结果为:10000 ...

  7. 青蛙跳台阶c语言递归函数,青蛙跳台阶问题的四种解法

    http://raychase.iteye.com/blog/1337359 题目:一只青蛙一次可以跳1级台阶,也可以跳2级.求该青蛙跳上一个n级的台阶总共有多少种跳法. 这道题还被ITEye放在了博 ...

  8. 剑指offer青蛙跳台阶问题

    (1)一只青蛙一次可以跳上 1 级台阶,也可以跳上2 级.求该青蛙跳上一个n 级的台阶总共有多少种跳法. //递归方式  public static int f(int n) { //参数合法性验证 ...

  9. 斐波那契数列及青蛙跳台阶问题

    题目1: 写一个函数,输入n,求斐波那契(Fibonacci)数列的第n项. 斐波那契(Fibonacci)数列定义例如以下: f(n)=⎧⎩⎨⎪⎪0,1,f(n−1)+f(n−2),n=0n=1n& ...

最新文章

  1. JframeMaxSize
  2. 「洛谷P1343」地震逃生 解题报告
  3. sdut 3363 驴友计划
  4. Fiori UI上创建的note和web client UI上note的对应关系
  5. Flutter Scaffold组件详情配制使用
  6. 系统集成资质培训 - 2013下半年系统集成资质申报及集成资质考试
  7. 两名黑客因发现特斯拉漏洞获Model 3一辆和3.5万美元奖金
  8. 【转】Qt串口通信专题教程
  9. php 唤醒http进程,真正的PHP多线程(绝非fork或者用http再开进程)_PHP教程
  10. paip.使用JAVASCRIPT开发桌面与WEB程序
  11. js代码格式化java api_Javascript 代码格式化(JsFormat)
  12. 三维可视化地籍管理平台如何实现地籍可视化管理?
  13. NYOJ 找球号(二)(哈希表)
  14. staruml 依赖于 libgcrypt11 (= 1.4.5);然而:未安装软件包 libgcrypt11。
  15. ept技术_每天5分钟跟我一起学电气之EPT的原理
  16. Powermill汽车件模具五轴数控CNC编程视频教程
  17. 工行二维码支付时代来了
  18. win10扬声器红叉_刚装了win10 小扬声器红叉没声音
  19. 华为路由器OSPF多区域配置
  20. 淘宝商品详情接口抓取

热门文章

  1. 项目03_淘宝用户分析
  2. k8s的ingress treafik部署使用
  3. 大分子葡聚糖-牛血清蛋白抗原偶联物(Dextran-BSA)|多糖-蛋白偶联物
  4. 判断密码是数字、小写字母、大写字母、特殊字符任意三个的正则表达式
  5. excel截取前、中、后几个字符串的方法
  6. Fedora 添加国内源(sohu, 163)
  7. linux环境下 go语言识别biso数据
  8. 网易公开课 matlab,科学网—如何保存网页上看到的视频 - 杨建功的博文
  9. python学习笔记(十七) Tkinter鼠标事件、树状层级目录和一些补充
  10. 最新前端Vue代码风格指南大全