leetcode:Frog Jump

来源:互联网 发布:海口网站快速优化排名 编辑:程序博客网 时间:2024/05/21 11:29

A frog is crossing a river. The river is divided into x units and at each unit there may or may not exist a stone. The frog can jump on a stone, but it must not jump into the water.

Given a list of stones' positions (in units) in sorted ascending order, determine if the frog is able to cross the river by landing on the last stone. Initially, the frog is on the first stone and assume the first jump must be 1 unit.

If the frog's last jump was k units, then its next jump must be eitherk - 1, k, or k + 1 units. Note that the frog can only jump in the forward direction.

Note:

  • The number of stones is ≥ 2 and is < 1,100.
  • Each stone's position will be a non-negative integer < 231.
  • The first stone's position is always 0.

Example 1:

[0,1,3,5,6,8,12,17]There are a total of 8 stones.The first stone at the 0th unit, second stone at the 1st unit,third stone at the 3rd unit, and so on...The last stone at the 17th unit.Return true. The frog can jump to the last stone by jumping 1 unit to the 2nd stone, then 2 units to the 3rd stone, then 2 units to the 4th stone, then 3 units to the 6th stone, 4 units to the 7th stone, and 5 units to the 8th stone.

Example 2:

[0,1,2,3,4,8,9,11]Return false. There is no way to jump to the last stone as the gap between the 5th and 6th stone is too large.

这道题归类与动态规划,意思相对明了,这里直接说解题思路。

其实基本的思路很简单,只要用最简单粗暴的方法一个个可能试就行,每次跳不下去就向前看看有没有其他的跳法,比如【0,1,2,3,6】这种情况,其他的便没什么多说的。这里要引入哈希表的方法来简化代码,通过为每一个石头点建立哈希表,来存储在当前点能够向前的步数,暴力向下进行。具体代码如下(附详细注释):

public boolean canCross(int[] stones){
        int len = stones.length;
        Map<Integer, HashSet<Integer>> map = new HashMap<>();
        for (int i =0; i < len; i ++) {                                               //为每一个石头点都创建哈希表,哈希表存储的内容是他能够向前跳的步数
            map.put(stones[i], new HashSet<>());
        }
        map.get(0).add(1);                                                          //初始起点只能跳1步
        for (int i =0; i < len - 1; i ++) {                                         //这里直接对每个点进行尝试                      
            for (int step : map.get(stones[i])) {                              //依次尝试不同的步数
                int to = step + stones[i];                                          //to是当前跳到的点(石头点 + 步数)
                if (to == stones[len - 1]) {                                        //到达终点!!
                    return true;
                }
                HashSet<Integer> tmp = map.get(to);                   //为到达的点建立哈希表,如果为石头点,则存储当前的跳数(同时存储跳数+/-1)
                if (tmp != null) {
                    tmp.add(step);
                    if (step > 1) {
                        tmp.add(step - 1);
                    }
                    tmp.add(step + 1);
                }
            }
        }
        return false;
    }

这个题我最开始虽然想到了暴力搜索,但是一直在实现上遇到了很多麻烦,也是我本人编程能力的问题,然而通过哈希表,极大简化了搜索步骤。以后要注重哈希表的使用!