Frog Jump

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 either k - 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.

思路:dfs,以为是一个递进的层级关系,当前跳k步,下一级跳k - 1, k, k + 1步;O(N^2)

class Solution {
    public boolean canCross(int[] stones) {
        HashSet<String> failed = new HashSet<>();
        HashSet<Integer> stoneSet = new HashSet<Integer>();
        for(int stone: stones) {
            stoneSet.add(stone);
        }
        return dfs(stoneSet, stones, failed, 0, 0);
    }
    
    private boolean dfs(HashSet<Integer> stoneSet, int[] stones, HashSet<String> failed, int pos, int jump) {
        //  base case;
        // 走到最后一个stone上了;
        if(pos == stones[stones.length - 1]) {
            return true;
        }
        // pos 不在stone set里面,表明踩空了;
        if(!stoneSet.contains(pos)) {
            return false;
        }
        // failed的状态里面有,直接返回;
        if(failed.contains(pos + "-" + jump)) {
            return false;
        }
        
        //接下来,三条路可以走:因为只能往右边走,所以所有的步骤必须>0;
        if(jump - 1 > 0 && dfs(stoneSet, stones, failed, pos + jump - 1, jump - 1)) {
            return true;
        }
        if(jump > 0 && dfs(stoneSet, stones, failed, pos + jump, jump)) {
            return true;
        }
        if(dfs(stoneSet, stones, failed, pos + jump + 1, jump + 1)) {
            return true;
        }
        // 如果还不行,那么这个状态只能是false,记录下来;
        failed.add(pos + "-" + jump);
        return false;
    }
}

这题也可以用BFS来做,层级关系的搜索;注意状态的搜集,因为是层级访问,所以都是最短的路径,如果visited里面有(pos + "-" + step)表明已经走过了,不需要再走一次了;

class Solution {
    public boolean canCross(int[] stones) {
        HashSet<Integer> stoneSet = new HashSet<>();
        for(int stone: stones) {
            stoneSet.add(stone);
        }
        int n = stones.length;
        Queue<int[]> queue = new LinkedList<int[]>();
        queue.offer(new int[]{0,0});
        HashSet<String> visited = new HashSet<>();
        visited.add(0 + "-" + 0);
        
        while(!queue.isEmpty()) {
            int[] node = queue.poll();
            int curpos = node[0];
            int curstep = node[1];
            for(int k = -1; k <= 1; k++) {
                int nextpos = curpos + curstep + k;
                int nextstep = curstep + k;
                if(nextpos == stones[n - 1]) {
                    return true;
                }
                if(stoneSet.contains(nextpos) 
                   && !visited.contains(nextpos + "-" + nextstep) 
                   && nextpos > curpos) {
                    queue.offer(new int[]{nextpos, nextstep});
                    visited.add(nextpos + "-" + nextstep);
                }
            }
        }
        return false;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值