- 31.0%

https://leetcode.com/problems/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.

1 | Example 1: |

1 | Example 2: |

6ms, September 19, 2016

https://discuss.leetcode.com/topic/59439/straight-forward-9ms-7-line-c-solution-with-explanation

方法一：

Straight-forward 9ms 7-line c++ solution with explanation

Search for the last stone in a depth-first way, prune those exceeding the [k-1,k+1] range. Well, I think the code is simple enough and need no more explanation.

1 | bool canCross(vector<int>& stones, int pos = 0, int k = 0) { |

我的代码实现：

上面的代码及本代码都会出现超时错误

1 | class Solution { |

方法二：

我的代码实现:

1 | class Solution { |

This can pass OJ at 9ms but is inefficient for extreme cases. (update: new test cases are added and the solution above no longer passes OJ, please see the solution below which takes 62ms) We can memorize the returns with minimum effort:

1 | unordered_map<int, bool> dp; |

The number of stones is less than 1100 so pos will always be less than 2^11 (2048).

Stone positions could be theoretically up to 2^31 but k is practically not possible to be that big for the parameter as the steps must start from 0 and 1 and at the 1100th step the greatest valid k would be 1100. So combining pos and k is safe here.

我的代码实现：

1 | class Solution { |

方法三：

我的代码实现：

1 | class Solution { |

使用一个map，记录每个位置为key，value为到达当前位置的所有步长的set集合。

平时不怎么用map再套set，这个方法很容易想到，也比较有用。

https://discuss.leetcode.com/topic/60194/c-9-lines-o-n-2-iterative-dp-solution

C++ 9 lines O(n^2) iterative DP solution

This solution is not as fast as some other O(n^2) DFS solutions possibly due to the OJ test cases. But it’s simple and clean.

Special thanks @farahcs and @vesion for correcting the bug in previous code.

1 | bool canCross(vector<int>& stones) { |

#### python

https://discuss.leetcode.com/topic/60080/python-dfs-easy-understanding-using-memo

Python DFS easy understanding using memo

Following is my backtracking solution using dict for memorization.

The memo dict is using for save those dead end. So when we get to the same stone with the same speed we don’t need to search further.

1 | class Solution(object): |

#### java

26ms, September 19, 2016

https://discuss.leetcode.com/topic/59337/easy-version-java

1 | public class Solution { |

https://leetcode.com/articles/frog-jump/

Approach #3 Using Memorization [Accepted]

Algorithm

Another problem with above approaches is that we can make the same function calls coming through different paths e.g. For a given currentIndexcurrentIndex, we can call the recursive function canCrosscanCross with the jumpsizejumpsize, say nn. This nn could be resulting from previous jumpsizejumpsize being n-1n−1,nn or n+1n+1. Thus, many redundant function calls could be made prolonging the running time. This redundancy can be removed by making use of memorization. We make use of a 2-d memomemo array, initialized by -1−1s, to store the result returned from a function call for a particular currentIndexcurrentIndex and jumpsizejumpsize. If the same currentIndexcurrentIndex and jumpsizejumpsize happens is encountered again, we can return the result directly using the memomemo array. This helps to prune the search tree to a great extent.

java

1 | public class Solution { |

Approach #4 Using Memorization with Binary Search [Accepted]

Algorithm

We can optimize the above memorization approach, if we make use of Binary Search to find if a stone exists at currentPostion + newjumpsizecurrentPostion+newjumpsize instead of searching linearly.

java

1 | public class Solution { |

Approach #5 Using Dynamic Programming[Accepted]

Algorithm

In the DP Approach, we make use of a hashmap mapmap which contains key:valuekey:value pairs such that keykey refers to the position at which a stone is present and valuevalue is a set containing the jumpsizejumpsize which can lead to the current stone position. We start by making a hashmap whose keykeys are all the positions at which a stone is present and the valuevalues are all empty except position 0 whose value contains 0. Then, we start traversing the elements(positions) of the given stone array in sequential order. For the currentPositioncurrentPosition, for every possible jumpsizejumpsize in the valuevalue set, we check if currentPosition + newjumpsizecurrentPosition+newjumpsize exists in the mapmap, where newjumpsizenewjumpsize can be either jumpsize-1jumpsize−1, jumpsizejumpsize, jumpsize+1jumpsize+1. If so, we append the corresponding valuevalue set with newjumpsizenewjumpsize. We continue in the same manner. If at the end, the valuevalue set corresponding to the last position is non-empty, we conclude that reaching the end is possible, otherwise, it isn’t.

For more understanding see this animation-

java

1 | public class Solution { |