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

x
+
cmd
stones = [0,1,3,5,6,8,12,17]

Output

x
+
cmd
true

#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

x
+
cmd
stones = [0,1,3,5,6,8,12,17]

Output

x
+
cmd
true

#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

x
+
cmd
stones = [0,1,2,3,4,8,9,11]

Output

x
+
cmd
false

#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

x
+
cmd
stones = [0,1,2,3,4,8,9,11]

Output

x
+
cmd
false

#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

x
+
cmd
stones = [0,1,3,5,6,8,12,17]

Output

x
+
cmd
true
Advertisements

Demonstration


Previous
#402 Leetcode Remove K Digits Solution in C, C++, Java, JavaScript, Python, C# Leetcode
Next
#404 Leetcode Sum of Left Leaves Solution in C, C++, Java, JavaScript, Python, C# Leetcode