Algorithm
Problem Name: 403. Frog Jump
A frog is crossing a river. The river is divided into some number of 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 can cross the river by landing on the last stone. Initially, the frog is on the first stone and assumes the first jump must be 1
unit.
If the frog's last jump was k
units, its next jump must be either k - 1
, k
, or k + 1
units. The frog can only jump in the forward direction.
Example 1:
Input: stones = [0,1,3,5,6,8,12,17] Output: true Explanation: 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:
Input: stones = [0,1,2,3,4,8,9,11] Output: false Explanation: There is no way to jump to the last stone as the gap between the 5th and 6th stone is too large.
Constraints:
2 <= stones.length <= 2000
0 <= stones[i] <= 231 - 1
stones[0] == 0
stones
is sorted in a strictly increasing order.
Code Examples
#1 Code Example with C Programming
Code -
C Programming
typedef struct {
int *p;
int n;
int sz;
} steps_t;
int bs(int *stones, int start, int end, int u) {
int mid, m;
if (start > end) return -1;
mid = start + (end - start) / 2;
m = stones[mid];
if (m == u) return mid;
else if (m < u) return bs(stones, mid + 1, end, u);
return bs(stones, start, mid - 1, u);
}
void add_step(int *stones, int sz, steps_t *units, int u, int s) {
int i, j;
steps_t *steps;
if (s == 0) return;
i = bs(stones, 0, sz - 1, u);
if (i == -1) return;
steps = &units[i];
for (j = 0; j < steps->n; j ++) {
if (steps->p[j] == s) return;
}
if (steps->sz == steps->n) {
if (steps->sz == 0) steps->sz = 10;
else steps->sz *= 2;
steps->p = realloc(steps->p, steps->sz * sizeof(int));
//assert(steps->p);
}
steps->p[steps->n ++] = s;
}
bool canCross(int* stones, int stonesSize) {
steps_t units[1100] = { 0 }, *steps;
int i, j, u, s;
bool ans = false;
if (stones[1] != 1) return false;
add_step(stones, stonesSize, units, 1, 1);
for (i = 1; i < stonesSize; i ++) {
u = stones[i];
steps = &units[i];
for (j = 0; j < steps->n; j ++) {
s = steps->p[j];
add_step(stones, stonesSize, units, u + s - 1, s - 1);
add_step(stones, stonesSize, units, u + s, s);
add_step(stones, stonesSize, units, u + s + 1, s + 1);
}
}
if (units[stonesSize - 1].n > 0) ans = true;
for (i = 0; i < 1100; i ++) {
if (units[i].p) free(units[i].p);
}
return ans;
}
Copy The Code &
Try With Live Editor
Input
Output
#2 Code Example with Java Programming
Code -
Java Programming
class Solution {
public boolean canCross(int[] stones) {
int[][] memo = new int[stones.length][stones.length];
for (int[] row : memo) {
Arrays.fill(row, -1);
}
return helper(stones, 0, 0, memo) == 1;
}
private int helper(int[] stones, int idx, int jumpSize, int[][] memo) {
if (memo[idx][jumpSize] >= 0) {
return memo[idx][jumpSize];
}
for (int i = idx + 1; i < stones.length; i++) {
int gap = stones[i] - stones[idx];
if (gap >= jumpSize - 1 && gap < = jumpSize + 1) {
if (helper(stones, i, gap, memo) == 1) {
memo[idx][gap] = 1;
return 1;
}
}
}
memo[idx][jumpSize] = (idx == stones.length - 1) ? 1 : 0;
return memo[idx][jumpSize];
}
}
Copy The Code &
Try With Live Editor
Input
Output
#3 Code Example with Javascript Programming
Code -
Javascript Programming
const canCross = function(stones) {
for (let i = 3; i < stones.length; i++) {
if (stones[i] > stones[i - 1] * 2) {
return false
}
}
const count = new Set(stones)
const lastStone = stones[stones.length - 1]
const position = [0]
const jump = [0]
while (position.length > 0) {
const nextPosition = position.pop()
const nextDistance = jump.pop()
for (let i = nextDistance - 1; i < = nextDistance + 1; i++) {
if (i <= 0) {
continue
}
const nextStone = nextPosition + i
if (nextStone == lastStone) {
return true
} else if (count.has(nextStone)) {
position.push(nextStone)
jump.push(i)
}
}
}
return false
}
Copy The Code &
Try With Live Editor
Input
Output
#4 Code Example with Python Programming
Code -
Python Programming
class Solution:
def canCross(self, stones):
memo, stones, target = {}, set(stones), stones[-1]
def dfs(unit, last):
if unit == target: return True
if (unit, last) not in memo:
memo[(unit, last)] = any(dfs(unit + move, move) for move in (last - 1, last, last + 1) if move and unit + move in stones)
return memo[(unit, last)]
return dfs(1, 1) if 1 in stones else False
Copy The Code &
Try With Live Editor
Input
Output
#5 Code Example with C# Programming
Code -
C# Programming
using System.Collections.Generic;
namespace LeetCode
{
public class _0403_FrogJump
{
public bool CanCross(int[] stones)
{
var seen = new HashSet < (int location, int step)>();
var stonesSet = new HashSet<int>(stones);
var last = stones[stones.Length - 1];
var stack = new Stack < (int location, int step)>();
stack.Push((0, 0));
while (stack.Count > 0)
{
(int location, int step) = stack.Pop();
if (seen.Contains((location, step))) continue;
seen.Add((location, step));
if (location == last) return true;
else if (location < last)
{
for (int i = step - 1; i < step + 2; i++)
{
if (i < = 0) continue;
if (stonesSet.Contains(location + i))
stack.Push((location + i, i));
}
}
}
return false;
}
}
}
Copy The Code &
Try With Live Editor
Input
Output