// Source : https://leetcode.com/problems/frog-jump/ // Author : Hao Chen // Date : 2016-11-12 /*************************************************************************************** * * 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 * Each stone's position will be a non-negative integer 31. * 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. ***************************************************************************************/ class Solution { public: bool canCross_recursion(vector& stones, int curr, int last_jump) { for(int i=curr+1; i last_jump + 1) return false; if (i == stones.size() - 1 || canCross_recursion(stones, i, next_jump)) return true; } return false; } bool canCross_recursion_with_cache(vector& stones, int curr, int last_jump, unordered_map>& cache) { //check the cache is hitted ? if (cache.find(curr) != cache.end() && cache[curr].find(last_jump)!=cache[curr].end()) { return cache[curr][last_jump]; } for(int i=curr+1; i last_jump + 1) break; if (i == stones.size() - 1 || canCross_recursion_with_cache(stones, i, next_jump, cache)) { cache[curr][last_jump] = true; return true; } } cache[curr][last_jump] = false; return false; } bool canCross_non_recursion(vector& stones) { // the `jumps` map store the all possible `last jumps` unordered_map> jumps = {{0, {0}}}; for(int i=0; i& stones) { //Burst Force solution -- accepted ~500ms return canCross_non_recursion(stones); //DFS with cache solution - accepted ~160ms unordered_map> cache; return canCross_recursion_with_cache(stones, 0, 0, cache); // Time Limit Error return canCross_recursion(stones, 0, 0); } };