New Problem Solution "Frog Jump"
This commit is contained in:
parent
d7c06e5ea1
commit
262af3ad6e
@ -10,6 +10,7 @@ LeetCode
|
||||
|---| ----- | -------- | ---------- |
|
||||
|405|[Convert a Number to Hexadecimal](https://leetcode.com/problems/convert-a-number-to-hexadecimal/) | [C++](./algorithms/cpp/convertANumberToHexadecimal/ConvertANumberToHexadecimal.cpp)|Easy|
|
||||
|404|[Sum of Left Leaves](https://leetcode.com/problems/sum-of-left-leaves/) | [C++](./algorithms/cpp/sumOfLeftLeaves/SumOfLeftLeaves.cpp)|Easy|
|
||||
|403|[Frog Jump](https://leetcode.com/problems/frog-jump/) | [C++](./algorithms/cpp/frogJump/FrogJump.cpp)|Hard|
|
||||
|402|[Remove K Digits](https://leetcode.com/problems/remove-k-digits/) | [C++](./algorithms/cpp/removeKDigits/RemoveKDigits.cpp)|Medium|
|
||||
|401|[Binary Watch](https://leetcode.com/problems/binary-watch/) | [C++](./algorithms/cpp/binaryWatch/BinaryWatch.cpp)|Easy|
|
||||
|400|[Nth Digit](https://leetcode.com/problems/nth-digit/) | [C++](./algorithms/cpp/nthDigit/NthDigit.cpp)|Easy|
|
||||
|
125
algorithms/cpp/frogJump/FrogJump.cpp
Normal file
125
algorithms/cpp/frogJump/FrogJump.cpp
Normal file
@ -0,0 +1,125 @@
|
||||
// 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<int>& stones, int curr, int last_jump) {
|
||||
for(int i=curr+1; i<stones.size(); i++){
|
||||
int next_jump = stones[i] - stones[curr];
|
||||
//the minimal jump is far exceed the current node, go to check next node.
|
||||
if (next_jump < last_jump - 1) continue;
|
||||
//cannot reach this one, then simple reture false;
|
||||
if (next_jump > 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<int>& stones, int curr, int last_jump,
|
||||
unordered_map<int, unordered_map<int, bool>>& 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<stones.size(); i++){
|
||||
int next_jump = stones[i] - stones[curr];
|
||||
if (next_jump < last_jump - 1) continue;
|
||||
if (next_jump > 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<int>& stones) {
|
||||
|
||||
// the `jumps` map store the all possible `last jumps`
|
||||
unordered_map<int, unordered_set<int>> jumps = {{0, {0}}};
|
||||
|
||||
for(int i=0; i<stones.size(); i++) {
|
||||
if (jumps.find(i) == jumps.end()){
|
||||
continue;
|
||||
}
|
||||
//for each possible last jump which reach the current node.
|
||||
for(int last_jump : jumps[i]) {
|
||||
//find the next nodes can be reached.
|
||||
for (int j=i+1; j < stones.size(); j++) {
|
||||
//ingore the rest node which cannot be reached
|
||||
if (stones[i] + last_jump + 1 < stones[j]) break;
|
||||
|
||||
// evaluated three possbile jumps for next node
|
||||
for (int next_jump = last_jump - 1; next_jump <= last_jump + 1; next_jump++) {
|
||||
if ( stones[i] + next_jump == stones[j] ) {
|
||||
jumps[j].insert(next_jump);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return jumps.find(stones.size()-1)!=jumps.end();
|
||||
}
|
||||
|
||||
bool canCross(vector<int>& stones) {
|
||||
|
||||
//Burst Force solution -- accepted ~500ms
|
||||
return canCross_non_recursion(stones);
|
||||
|
||||
//DFS with cache solution - accepted ~160ms
|
||||
unordered_map<int, unordered_map<int, bool>> cache;
|
||||
return canCross_recursion_with_cache(stones, 0, 0, cache);
|
||||
|
||||
// Time Limit Error
|
||||
return canCross_recursion(stones, 0, 0);
|
||||
|
||||
}
|
||||
};
|
Loading…
x
Reference in New Issue
Block a user