Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 计算青蛙到达河对岸所需的最小跳跃次数_Java_Arrays_Algorithm_Performance - Fatal编程技术网

Java 计算青蛙到达河对岸所需的最小跳跃次数

Java 计算青蛙到达河对岸所需的最小跳跃次数,java,arrays,algorithm,performance,Java,Arrays,Algorithm,Performance,我处理下面提供的一个可编码性问题 斐波那契序列使用以下递归公式定义: F(0) = 0 F(1) = 1 F(M) = F(M - 1) + F(M - 2) if M >= 2 一只小青蛙想去河的对岸。青蛙最初位于河流的一个河岸(位置−1) 并且想去另一家银行(位置N)。青蛙可以跳过任何距离F(K),其中F(K)是第K个斐波那契数。幸运的是,河上有许多树叶,青蛙可以在树叶之间跳跃,但只能朝着N位置河岸的方向跳 河上的叶子用一个由N个整数组成的数组表示。数组A的连续元素表示从0到N的连续

我处理下面提供的一个可编码性问题

斐波那契序列使用以下递归公式定义:

F(0) = 0
F(1) = 1
F(M) = F(M - 1) + F(M - 2) if M >= 2
一只小青蛙想去河的对岸。青蛙最初位于河流的一个河岸(位置−1) 并且想去另一家银行(位置N)。青蛙可以跳过任何距离F(K),其中F(K)是第K个斐波那契数。幸运的是,河上有许多树叶,青蛙可以在树叶之间跳跃,但只能朝着N位置河岸的方向跳

河上的叶子用一个由N个整数组成的数组表示。数组A的连续元素表示从0到N的连续位置− 1在河上。阵列A仅包含0和/或1:

0表示没有叶的位置; 1表示包含叶的位置。 目标是计算青蛙能够跳到河对岸的最小跳跃次数(从位置)−1到位置N)。青蛙可以在两个位置之间跳跃−1和N(河岸)以及每个包含叶子的位置

例如,考虑数组A这样:

A[0] = 0
A[1] = 0
A[2] = 0
A[3] = 1
A[4] = 1
A[5] = 0
A[6] = 1
A[7] = 0
A[8] = 0
A[9] = 0
A[10] = 0
青蛙可以跳三次,长度F(5)=5、F(3)=2和F(5)=5

编写一个函数:

class Solution { public int solution(int[] A); }
给定一个由N个整数组成的数组A,返回青蛙能够到达河对岸的最小跳跃次数。如果青蛙无法到达河的另一边,该功能应返回−一,

例如,假设:

A[0] = 0
A[1] = 0
A[2] = 0
A[3] = 1
A[4] = 1
A[5] = 0
A[6] = 1
A[7] = 0
A[8] = 0
A[9] = 0
A[10] = 0
函数应该返回3,如上所述

假设:

N是范围
[0..100000]
内的整数; 数组A的每个元素都是一个整数,可以具有以下值之一:0、1。 复杂性:

预计最坏情况的时间复杂度为
O(N*log(N))
; 预计最坏情况下的空间复杂度为
O(N)
(不计算输入参数所需的存储)

我写了下面的解决方案

class Solution {
    private class Jump {
        int position;
        int number;

        public int getPosition() {
            return position;
        }

        public int getNumber() {
            return number;
        }

        public Jump(int pos, int number) {
            this.position = pos;
            this.number = number;
        }
    }

    public int solution(int[] A) {

        int N = A.length;

        List<Integer> fibs = getFibonacciNumbers(N + 1);

        Stack<Jump> jumps = new Stack<>();
        jumps.push(new Jump(-1, 0));

        boolean[] visited = new boolean[N];

        while (!jumps.isEmpty()) {

            Jump jump = jumps.pop();

            int position = jump.getPosition();
            int number = jump.getNumber();

            for (int fib : fibs) {

                if (position + fib > N) {
                    break;
                } else if (position + fib == N) {
                    return number + 1;
                } else if (!visited[position + fib] && A[position + fib] == 1) {

                    visited[position + fib] = true;
                    jumps.add(new Jump(position + fib, number + 1));
                }
            }
        }

        return -1;
    }


    private List<Integer> getFibonacciNumbers(int N) {

        List<Integer> list = new ArrayList<>();

        for (int i = 0; i < 2; i++) {
            list.add(i);
        }

        int i = 2;

        while (list.get(list.size() - 1) <= N) {

            list.add(i, (list.get(i - 1) + list.get(i - 2)));
            i++;
        }

        for (i = 0; i < 2; i++) {
            list.remove(i);
        }

        return list;
    }




    public static void main(String[] args) {

    int[] A = new int[11];

    A[0] = 0;
    A[1] = 0;
    A[2] = 0;
    A[3] = 1;
    A[4] = 1;
    A[5] = 0;
    A[6] = 1;
    A[7] = 0;
    A[8] = 0;
    A[9] = 0;
    A[10] = 0;

    System.out.println(solution(A));
   }
}
类解决方案{
私人跳级{
内部位置;
整数;
public int getPosition(){
返回位置;
}
public int getNumber(){
返回号码;
}
公共跳转(内部位置,内部编号){
这个位置=位置;
这个数字=数字;
}
}
公共int解决方案(int[]A){
int N=A.长度;
列表fibs=getFibonacciNumbers(N+1);
堆栈跳转=新堆栈();
跳跃。推(新跳跃(-1,0));
boolean[]访问=新的boolean[N];
而(!jumps.isEmpty()){
Jump-Jump=jumps.pop();
int position=jump.getPosition();
int number=jump.getNumber();
for(int-fib:fibs){
如果(位置+fib>N){
打破
}否则如果(位置+fib==N){
返回号码+1;
}如果(!访问了[position+fib]&&A[position+fib]==1),则为else{
已访问[位置+fib]=真;
添加(新的跳转(位置+fib,数字+1));
}
}
}
返回-1;
}
私有列表getFibonacciNumbers(int N){
列表=新的ArrayList();
对于(int i=0;i<2;i++){
列表.添加(i);
}
int i=2;
而(list.get(list.size()-1)可以应用算法来解决这个问题。
在我的解决方案中,我预先计算了斐波那契数。并应用背包算法来解决它。它包含重复的代码,没有太多的时间来重构它。具有相同代码的在线ide在

import java.util.*;
班长{
公共静态int解决方案(int[]A){
int N=A.长度;
int inf=1000000;
int[]fibs={1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765,10946,17711,28657,46368,75025};
int[]移动=新int[N+1];

对于(inti=0;i100%得到C中的溶液

typedef struct state {
    int pos;
    int step;
}state;
int solution(int A[], int N) {

    int f1 = 0;
    int f2 = 1;
    int count = 2;
    // precalculating count of maximum possible fibonacci numbers to allocate array in next loop. since this is C language we do not have flexible dynamic structure as in C++
    while(1)
    {
        int f3 =  f2 + f1;
        if(f3 > N)
            break;
        f1 = f2;
        f2 = f3;
        ++count;
    }
    int fib[count+1];
    fib[0] = 0;
    fib[1] = 1;
    int i = 2;
    // calculating fibonacci numbers in array
    while(1)
    {
        fib[i] =  fib[i-1] + fib[i-2];
        if(fib[i] > N)
            break;
        ++i;
    }
    // reversing the fibonacci numbers because we need to create minumum jump counts with bigger jumps
    for(int j = 0, k = count; j < count/2; j++,k--)
    {
        int t = fib[j];
        fib[j] = fib[k];
        fib[k] = t;
    }
    state q[N];
    int front = 0 ;
    int rear = 0;
    q[0].pos = -1;
    q[0].step = 0;
    int que_s = 1;
    while(que_s > 0)
    {
        state s =  q[front];
        front++;
        que_s--;
        for(int i = 0; i <= count; i++)
        {
            int nextpo = s.pos + fib[i];
            if(nextpo == N)
            {
                return s.step+1;
            }
            else if(nextpo > N || nextpo < 0 || A[nextpo] == 0){
           
                continue;  
            }
            else
            {
                q[++rear].pos = nextpo;
                q[rear].step = s.step + 1;
                que_s++;
                A[nextpo] = 0;
            }
        }
    }
    return -1;
}
typedef结构状态{
int pos;
整数步;
}国家;
整数解(整数A[],整数N){
int f1=0;
int f2=1;
整数计数=2;
在下一个循环中分配数组的最大可能斐波那契数,因为这是C语言,所以C++中没有灵活的动态结构。
而(1)
{
int f3=f2+f1;
如果(f3>N)
打破
f1=f2;
f2=f3;
++计数;
}
int fib[计数+1];
fib[0]=0;
fib[1]=1;
int i=2;
//计算数组中的斐波那契数
而(1)
{
fib[i]=fib[i-1]+fib[i-2];
if(fib[i]>N)
打破
++一,;
}
//反转斐波那契数,因为我们需要创建具有较大跳跃的最小跳跃计数
对于(int j=0,k=count;j0)
{
状态s=q[前面];
前端++;
你知道吗;
对于(int i=0;i N | | nextpo<0 | | A[nextpo]==0){
继续;
}
其他的
{
q[++后].pos=nextpo;
q[后]。步骤=秒。步骤+1;
que_s++;
A[nextpo]=0;
}
}
}
返回-1;
}

通过简单的BFS获得100%的收益:

public class Jump {
    int pos;
    int move;
    public Jump(int pos, int move) {
        this.pos = pos;
        this.move = move;
    }
}

public int solution(int[] A) {

    int n = A.length;
    List < Integer > fibs = fibArray(n + 1);
    Queue < Jump > positions = new LinkedList < Jump > ();
    boolean[] visited = new boolean[n + 1];

    if (A.length <= 2)
        return 1;

    for (int i = 0; i < fibs.size(); i++) {
        int initPos = fibs.get(i) - 1;
        if (A[initPos] == 0)
            continue;
        positions.add(new Jump(initPos, 1));
        visited[initPos] = true;
    }

    while (!positions.isEmpty()) {
        Jump jump = positions.remove();
        for (int j = fibs.size() - 1; j >= 0; j--) {
            int nextPos = jump.pos + fibs.get(j);
            if (nextPos == n)
                return jump.move + 1;
            else if (nextPos < n && A[nextPos] == 1 && !visited[nextPos]) {
                positions.add(new Jump(nextPos, jump.move + 1));
                visited[nextPos] = true;
            }
        }
    }


    return -1;
}


private List < Integer > fibArray(int n) {
    List < Integer > fibs = new ArrayList < > ();
    fibs.add(1);
    fibs.add(2);
    while (fibs.get(fibs.size() - 1) + fibs.get(fibs.size() - 2) <= n) {
        fibs.add(fibs.get(fibs.size() - 1) + fibs.get(fibs.size() - 2));
    }
    return fibs;
}
公共类跳转{
int pos;
int-move;
公共跳转(内部位置、内部移动){
this.pos=pos;
this.move=移动;
}
}
公共int解决方案(int[]A){
int n=A.长度;
Listfibs=fibArray(n+1);
队列位置=新链接列表();
布尔[]访问=新布尔[n+1];
如果(A.length=0;j--){
int nextP
public class Jump {
    int pos;
    int move;
    public Jump(int pos, int move) {
        this.pos = pos;
        this.move = move;
    }
}

public int solution(int[] A) {

    int n = A.length;
    List < Integer > fibs = fibArray(n + 1);
    Queue < Jump > positions = new LinkedList < Jump > ();
    boolean[] visited = new boolean[n + 1];

    if (A.length <= 2)
        return 1;

    for (int i = 0; i < fibs.size(); i++) {
        int initPos = fibs.get(i) - 1;
        if (A[initPos] == 0)
            continue;
        positions.add(new Jump(initPos, 1));
        visited[initPos] = true;
    }

    while (!positions.isEmpty()) {
        Jump jump = positions.remove();
        for (int j = fibs.size() - 1; j >= 0; j--) {
            int nextPos = jump.pos + fibs.get(j);
            if (nextPos == n)
                return jump.move + 1;
            else if (nextPos < n && A[nextPos] == 1 && !visited[nextPos]) {
                positions.add(new Jump(nextPos, jump.move + 1));
                visited[nextPos] = true;
            }
        }
    }


    return -1;
}


private List < Integer > fibArray(int n) {
    List < Integer > fibs = new ArrayList < > ();
    fibs.add(1);
    fibs.add(2);
    while (fibs.get(fibs.size() - 1) + fibs.get(fibs.size() - 2) <= n) {
        fibs.add(fibs.get(fibs.size() - 1) + fibs.get(fibs.size() - 2));
    }
    return fibs;
}
def solution(a)
  f = 2.step.inject([1,2]) {|acc,e| acc[e] = acc[e-1] + acc[e-2]; break(acc) if acc[e] > a.size + 1;acc }.reverse
  mins = []

  (a.size + 1).times do |i|
    next mins[i] = -1 if i < a.size && a[i] == 0

    mins[i] = f.inject(nil) do |min, j|
        k = i - j
        next min if k < -1
        break 1 if k == -1
        next min if mins[k] < 0
        [mins[k] + 1, min || Float::INFINITY].min
    end || -1
  end

  mins[a.size]
end
import java.util.*;


class Solution {

        private static class State {

        int pos;
        int step;

        public State(int pos, int step) {

            this.pos = pos;
            this.step = step;
        }
    }


    public static int solution(int A[]) {

        int N = A.length;

        int f1 = 0;
        int f2 = 1;

        int count = 2;

        while (true) {

            int f3 = f2 + f1;

            if (f3 > N) {
                break;
            }

            f1 = f2;
            f2 = f3;

            ++count;
        }


        int[] fib = new int[count + 1];

        fib[0] = 0;
        fib[1] = 1;

        int i = 2;

        while (true) {

            fib[i] = fib[i - 1] + fib[i - 2];

            if (fib[i] > N) {
                break;
            }

            ++i;
        }

        for (int j = 0, k = count; j < count / 2; j++, k--) {

            int t = fib[j];

            fib[j] = fib[k];
            fib[k] = t;
        }

        State[] q = new State[N];

        for (int j = 0; j < N; j++) {

            q[j] = new State(-1,0);
        }

        int front = 0;
        int rear = 0;

        // q[0].pos = -1;
        // q[0].step = 0;

        int que_s = 1;

        while (que_s > 0) {

            State s = q[front];

            front++;
            que_s--;

            for (i = 0; i <= count; i++) {

                int nextpo = s.pos + fib[i];

                if (nextpo == N) {
                    return s.step + 1;
                }

                //
                else if (nextpo > N || nextpo < 0 || A[nextpo] == 0) {
                    continue;
                }

                //
                else {

                    q[++rear].pos = nextpo;
                    q[rear].step = s.step + 1;

                    que_s++;

                    A[nextpo] = 0;
                }
            }
        }

        return -1;
    }
}
function solution(A) {
  const createFibs = n => {
    const fibs = Array(n + 2).fill(null)
    fibs[1] = 1
    for (let i = 2; i < n + 1; i++) {
      fibs[i] = fibs[i - 1] + fibs[i - 2]
    }
    return fibs
  }
  const createJumps = (A, fibs) => {
    const jumps = Array(A.length + 1).fill(null)
    let prev = null
    for (i = 2; i < fibs.length; i++) {
      const j = -1 + fibs[i]
      if (j > A.length) break
      if (j === A.length || A[j] === 1) {
        jumps[j] = 1
        if (prev === null) prev = j
      }
    }
    if (prev === null) {
      jumps[A.length] = -1
      return jumps
    }
    while (prev < A.length) {
      for (let i = 2; i < fibs.length; i++) {
        const j = prev + fibs[i]
        if (j > A.length) break
        if (j === A.length || A[j] === 1) {
          const x = jumps[prev] + 1
          const y = jumps[j]
          jumps[j] = y === null ? x : Math.min(y, x)
        }
      }
      prev++
      while (prev < A.length) {
        if (jumps[prev] !== null) break
        prev++
      }
    }
    if (jumps[A.length] === null) jumps[A.length] = -1
    return jumps
  }
  const fibs = createFibs(26)
  const jumps = createJumps(A, fibs)
  return jumps[A.length]
}

const A = [0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0]
console.log(A)
const s = solution(A)
console.log(s)
def gen_fib(n):
    fn = [0,1]
    i = 2
    s = 2
    while s < n:
        s = fn[i-2] + fn[i-1]
        fn.append(s)
        i+=1
    return fn

def new_paths(A, n, last_pos, fn):
    """
    Given an array A of len n.
    From index last_pos which numbers in fn jump to a leaf?
    returns list: set of indexes with leaves.
    """
    paths = []
    for f in fn:
        new_pos = last_pos + f
        if new_pos == n or (new_pos < n and A[new_pos]):
            paths.append(new_pos)
    return path

def solution(A):
    n = len(A)
    if n < 3:
        return 1

    # A.append(1) # mark final jump
    fn = sorted(gen_fib(100000)[2:]) # Fib numbers with 0, 1, 1, 2..  clipped to just 1, 2..
    # print(fn)
    paths = set([-1]) # locate all the leaves that are one fib jump from the start position.

    jump = 1
    while True:
        # Considering each of the previous jump positions - How many leaves from there are one fib jump away
        paths =  set([idx for pos in paths for idx in new_paths(A, n, pos, fn)])

        # no new jumps means game over!
        if not paths:
            break

        # If there was a result in the new jumps record that
        if n in paths:
            return jump
            
        jump += 1

    return -1
function solution(A) {
    function fibonacciUntilNumber(n) {
        const fib = [0,1];
        while (true) {
            let newFib = fib[fib.length - 1] + fib[fib.length - 2];
            if (newFib > n) {
                break;
            }
            fib.push(newFib);
        }
        return fib.slice(2);
    }
    A.push(1);
    const fibSet = fibonacciUntilNumber(A.length);
    if (fibSet.includes(A.length)) return 1;
    const reachable = Array.from({length: A.length}, () => -1);

    fibSet.forEach(jump => {
        if (A[jump - 1] === 1) {
            reachable[jump - 1] = 1;
        }
    })

    for (let index = 0; index < A.length; index++) {
        if (A[index] === 0 || reachable[index] > 0) {
            continue;
        }
        let minValue = 100005;
        for (let jump of fibSet) {
            let previousIndex = index - jump;
            if (previousIndex < 0) {
                break;
            }
            if (reachable[previousIndex] > 0 && minValue > reachable[previousIndex]) {
                minValue = reachable[previousIndex];
            }
        }
        if (minValue !== 100005) {
            reachable[index] = minValue + 1;
        }
    }
    return reachable[A.length - 1];
}